vk/formats: Document new meaning of anv_format::cpp
[mesa.git] / src / vulkan / pipeline.c
index 30185dd0b79b71171941f56cd05fd9b5badb66e8..f574038f83f072bcde9aae1be7f78ee6aa058e46 100644 (file)
@@ -31,7 +31,7 @@
 
 // Shader functions
 
-VkResult VKAPI vkCreateShader(
+VkResult anv_CreateShader(
     VkDevice                                    _device,
     const VkShaderCreateInfo*                   pCreateInfo,
     VkShader*                                   pShader)
@@ -62,11 +62,13 @@ emit_vertex_input(struct anv_pipeline *pipeline, VkPipelineVertexInputCreateInfo
    const uint32_t num_dwords = 1 + info->attributeCount * 2;
    uint32_t *p;
    bool instancing_enable[32];
-   
+
+   pipeline->vb_used = 0;
    for (uint32_t i = 0; i < info->bindingCount; i++) {
       const VkVertexInputBindingDescription *desc =
          &info->pVertexBindingDescriptions[i];
-      
+
+      pipeline->vb_used |= 1 << desc->binding;
       pipeline->binding_stride[desc->binding] = desc->strideInBytes;
 
       /* Step rate is programmed per vertex element (attribute), not
@@ -94,13 +96,13 @@ emit_vertex_input(struct anv_pipeline *pipeline, VkPipelineVertexInputCreateInfo
       struct GEN8_VERTEX_ELEMENT_STATE element = {
          .VertexBufferIndex = desc->binding,
          .Valid = true,
-         .SourceElementFormat = format->format,
+         .SourceElementFormat = format->surface_format,
          .EdgeFlagEnable = false,
          .SourceElementOffset = desc->offsetInBytes,
          .Component0Control = VFCOMP_STORE_SRC,
-         .Component1Control = format->channels >= 2 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
-         .Component2Control = format->channels >= 3 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
-         .Component3Control = format->channels >= 4 ? VFCOMP_STORE_SRC : VFCOMP_STORE_1_FP
+         .Component1Control = format->num_channels >= 2 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component2Control = format->num_channels >= 3 ? VFCOMP_STORE_SRC : VFCOMP_STORE_0,
+         .Component3Control = format->num_channels >= 4 ? VFCOMP_STORE_SRC : VFCOMP_STORE_1_FP
       };
       GEN8_VERTEX_ELEMENT_STATE_pack(NULL, &p[1 + i * 2], &element);
 
@@ -127,17 +129,17 @@ emit_ia_state(struct anv_pipeline *pipeline,
               const struct anv_pipeline_create_info *extra)
 {
    static const uint32_t vk_to_gen_primitive_type[] = {
-      [VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = _3DPRIM_POINTLIST,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = _3DPRIM_LINELIST,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = _3DPRIM_LINESTRIP,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = _3DPRIM_TRILIST,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = _3DPRIM_TRISTRIP,
-      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = _3DPRIM_TRIFAN,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ] = _3DPRIM_LINELIST_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ] = _3DPRIM_LISTSTRIP_ADJ,
+      [VK_PRIMITIVE_TOPOLOGY_POINT_LIST]        = _3DPRIM_POINTLIST,
+      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST]         = _3DPRIM_LINELIST,
+      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP]        = _3DPRIM_LINESTRIP,
+      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST]     = _3DPRIM_TRILIST,
+      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP]    = _3DPRIM_TRISTRIP,
+      [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN]      = _3DPRIM_TRIFAN,
+      [VK_PRIMITIVE_TOPOLOGY_LINE_LIST_ADJ]     = _3DPRIM_LINELIST_ADJ,
+      [VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_ADJ]    = _3DPRIM_LISTSTRIP_ADJ,
       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_ADJ] = _3DPRIM_TRILIST_ADJ,
       [VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_ADJ] = _3DPRIM_TRISTRIP_ADJ,
-      [VK_PRIMITIVE_TOPOLOGY_PATCH] = _3DPRIM_PATCHLIST_1
+      [VK_PRIMITIVE_TOPOLOGY_PATCH]             = _3DPRIM_PATCHLIST_1
    };
    uint32_t topology = vk_to_gen_primitive_type[info->topology];
 
@@ -154,29 +156,28 @@ emit_ia_state(struct anv_pipeline *pipeline,
 static void
 emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
               const struct anv_pipeline_create_info *extra)
-
 {
    static const uint32_t vk_to_gen_cullmode[] = {
-      [VK_CULL_MODE_NONE] = CULLMODE_NONE,
-      [VK_CULL_MODE_FRONT] = CULLMODE_FRONT,
-      [VK_CULL_MODE_BACK] = CULLMODE_BACK,
-      [VK_CULL_MODE_FRONT_AND_BACK] = CULLMODE_BOTH
+      [VK_CULL_MODE_NONE]                       = CULLMODE_NONE,
+      [VK_CULL_MODE_FRONT]                      = CULLMODE_FRONT,
+      [VK_CULL_MODE_BACK]                       = CULLMODE_BACK,
+      [VK_CULL_MODE_FRONT_AND_BACK]             = CULLMODE_BOTH
    };
 
    static const uint32_t vk_to_gen_fillmode[] = {
-      [VK_FILL_MODE_POINTS] = RASTER_POINT,
-      [VK_FILL_MODE_WIREFRAME] = RASTER_WIREFRAME,
-      [VK_FILL_MODE_SOLID] = RASTER_SOLID
+      [VK_FILL_MODE_POINTS]                     = RASTER_POINT,
+      [VK_FILL_MODE_WIREFRAME]                  = RASTER_WIREFRAME,
+      [VK_FILL_MODE_SOLID]                      = RASTER_SOLID
    };
 
    static const uint32_t vk_to_gen_front_face[] = {
-      [VK_FRONT_FACE_CCW] = CounterClockwise,
-      [VK_FRONT_FACE_CW] = Clockwise
+      [VK_FRONT_FACE_CCW]                       = CounterClockwise,
+      [VK_FRONT_FACE_CW]                        = Clockwise
    };
    
    static const uint32_t vk_to_gen_coordinate_origin[] = {
-      [VK_COORDINATE_ORIGIN_UPPER_LEFT] = UPPERLEFT,
-      [VK_COORDINATE_ORIGIN_LOWER_LEFT] = LOWERLEFT
+      [VK_COORDINATE_ORIGIN_UPPER_LEFT]         = UPPERLEFT,
+      [VK_COORDINATE_ORIGIN_LOWER_LEFT]         = LOWERLEFT
    };
 
    struct GEN8_3DSTATE_SF sf = {
@@ -191,18 +192,21 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
       .PointWidthSource = info->programPointSize ? Vertex : State,
    };
 
-   /* bool32_t                                    rasterizerDiscardEnable; */
-
+   /* FINISHME: bool32_t rasterizerDiscardEnable; */
 
    GEN8_3DSTATE_SF_pack(NULL, pipeline->state_sf, &sf);
 
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_RASTER,
-                  .FrontWinding = vk_to_gen_front_face[info->frontFace],
-                  .CullMode = vk_to_gen_cullmode[info->cullMode],
-                  .FrontFaceFillMode = vk_to_gen_fillmode[info->fillMode],
-                  .BackFaceFillMode = vk_to_gen_fillmode[info->fillMode],
-                  .ScissorRectangleEnable = !(extra && extra->disable_scissor),
-                  .ViewportZClipTestEnable = info->depthClipEnable);
+   struct GEN8_3DSTATE_RASTER raster = {
+      GEN8_3DSTATE_RASTER_header,
+      .FrontWinding = vk_to_gen_front_face[info->frontFace],
+      .CullMode = vk_to_gen_cullmode[info->cullMode],
+      .FrontFaceFillMode = vk_to_gen_fillmode[info->fillMode],
+      .BackFaceFillMode = vk_to_gen_fillmode[info->fillMode],
+      .ScissorRectangleEnable = !(extra && extra->disable_scissor),
+      .ViewportZClipTestEnable = info->depthClipEnable
+   };
+
+   GEN8_3DSTATE_RASTER_pack(NULL, pipeline->state_raster, &raster);
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SBE,
                   .ForceVertexURBEntryReadLength = false,
@@ -214,7 +218,158 @@ emit_rs_state(struct anv_pipeline *pipeline, VkPipelineRsStateCreateInfo *info,
 
 }
 
-VkResult VKAPI vkCreateGraphicsPipeline(
+static void
+emit_cb_state(struct anv_pipeline *pipeline, VkPipelineCbStateCreateInfo *info)
+{
+   struct anv_device *device = pipeline->device;
+
+   static const uint32_t vk_to_gen_logic_op[] = {
+      [VK_LOGIC_OP_COPY]                        = LOGICOP_COPY,
+      [VK_LOGIC_OP_CLEAR]                       = LOGICOP_CLEAR,
+      [VK_LOGIC_OP_AND]                         = LOGICOP_AND,
+      [VK_LOGIC_OP_AND_REVERSE]                 = LOGICOP_AND_REVERSE,
+      [VK_LOGIC_OP_AND_INVERTED]                = LOGICOP_AND_INVERTED,
+      [VK_LOGIC_OP_NOOP]                        = LOGICOP_NOOP,
+      [VK_LOGIC_OP_XOR]                         = LOGICOP_XOR,
+      [VK_LOGIC_OP_OR]                          = LOGICOP_OR,
+      [VK_LOGIC_OP_NOR]                         = LOGICOP_NOR,
+      [VK_LOGIC_OP_EQUIV]                       = LOGICOP_EQUIV,
+      [VK_LOGIC_OP_INVERT]                      = LOGICOP_INVERT,
+      [VK_LOGIC_OP_OR_REVERSE]                  = LOGICOP_OR_REVERSE,
+      [VK_LOGIC_OP_COPY_INVERTED]               = LOGICOP_COPY_INVERTED,
+      [VK_LOGIC_OP_OR_INVERTED]                 = LOGICOP_OR_INVERTED,
+      [VK_LOGIC_OP_NAND]                        = LOGICOP_NAND,
+      [VK_LOGIC_OP_SET]                         = LOGICOP_SET,
+   };
+
+   static const uint32_t vk_to_gen_blend[] = {
+      [VK_BLEND_ZERO]                           = BLENDFACTOR_ZERO,
+      [VK_BLEND_ONE]                            = BLENDFACTOR_ONE,
+      [VK_BLEND_SRC_COLOR]                      = BLENDFACTOR_SRC_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC_COLOR]            = BLENDFACTOR_INV_SRC_COLOR,
+      [VK_BLEND_DEST_COLOR]                     = BLENDFACTOR_DST_COLOR,
+      [VK_BLEND_ONE_MINUS_DEST_COLOR]           = BLENDFACTOR_INV_DST_COLOR,
+      [VK_BLEND_SRC_ALPHA]                      = BLENDFACTOR_SRC_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC_ALPHA]            = BLENDFACTOR_INV_SRC_ALPHA,
+      [VK_BLEND_DEST_ALPHA]                     = BLENDFACTOR_DST_ALPHA,
+      [VK_BLEND_ONE_MINUS_DEST_ALPHA]           = BLENDFACTOR_INV_DST_ALPHA,
+      [VK_BLEND_CONSTANT_COLOR]                 = BLENDFACTOR_CONST_COLOR,
+      [VK_BLEND_ONE_MINUS_CONSTANT_COLOR]       = BLENDFACTOR_INV_CONST_COLOR,
+      [VK_BLEND_CONSTANT_ALPHA]                 = BLENDFACTOR_CONST_ALPHA,
+      [VK_BLEND_ONE_MINUS_CONSTANT_ALPHA]       = BLENDFACTOR_INV_CONST_ALPHA,
+      [VK_BLEND_SRC_ALPHA_SATURATE]             = BLENDFACTOR_SRC_ALPHA_SATURATE,
+      [VK_BLEND_SRC1_COLOR]                     = BLENDFACTOR_SRC1_COLOR,
+      [VK_BLEND_ONE_MINUS_SRC1_COLOR]           = BLENDFACTOR_INV_SRC1_COLOR,
+      [VK_BLEND_SRC1_ALPHA]                     = BLENDFACTOR_SRC1_ALPHA,
+      [VK_BLEND_ONE_MINUS_SRC1_ALPHA]           = BLENDFACTOR_INV_SRC1_ALPHA,
+   };
+
+   static const uint32_t vk_to_gen_blend_op[] = {
+      [VK_BLEND_OP_ADD]                         = BLENDFUNCTION_ADD,
+      [VK_BLEND_OP_SUBTRACT]                    = BLENDFUNCTION_SUBTRACT,
+      [VK_BLEND_OP_REVERSE_SUBTRACT]            = BLENDFUNCTION_REVERSE_SUBTRACT,
+      [VK_BLEND_OP_MIN]                         = BLENDFUNCTION_MIN,
+      [VK_BLEND_OP_MAX]                         = BLENDFUNCTION_MAX,
+   };
+
+   uint32_t num_dwords = 1 + info->attachmentCount * 2;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   struct GEN8_BLEND_STATE blend_state = {
+      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+   };
+
+   uint32_t *state = pipeline->blend_state.map;
+   GEN8_BLEND_STATE_pack(NULL, state, &blend_state);
+
+   for (uint32_t i = 0; i < info->attachmentCount; i++) {
+      const VkPipelineCbAttachmentState *a = &info->pAttachments[i];
+
+      struct GEN8_BLEND_STATE_ENTRY entry = {
+         .LogicOpEnable = info->logicOpEnable,
+         .LogicOpFunction = vk_to_gen_logic_op[info->logicOp],
+         .ColorBufferBlendEnable = a->blendEnable,
+         .PreBlendSourceOnlyClampEnable = false,
+         .PreBlendColorClampEnable = false,
+         .PostBlendColorClampEnable = false,
+         .SourceBlendFactor = vk_to_gen_blend[a->srcBlendColor],
+         .DestinationBlendFactor = vk_to_gen_blend[a->destBlendColor],
+         .ColorBlendFunction = vk_to_gen_blend_op[a->blendOpColor],
+         .SourceAlphaBlendFactor = vk_to_gen_blend[a->srcBlendAlpha],
+         .DestinationAlphaBlendFactor = vk_to_gen_blend[a->destBlendAlpha],
+         .AlphaBlendFunction = vk_to_gen_blend_op[a->blendOpAlpha],
+         .WriteDisableAlpha = !(a->channelWriteMask & VK_CHANNEL_A_BIT),
+         .WriteDisableRed = !(a->channelWriteMask & VK_CHANNEL_R_BIT),
+         .WriteDisableGreen = !(a->channelWriteMask & VK_CHANNEL_G_BIT),
+         .WriteDisableBlue = !(a->channelWriteMask & VK_CHANNEL_B_BIT),
+      };
+
+      GEN8_BLEND_STATE_ENTRY_pack(NULL, state + i * 2 + 1, &entry);
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_BLEND_STATE_POINTERS,
+                  .BlendStatePointer = pipeline->blend_state.offset,
+                  .BlendStatePointerValid = true);
+}
+
+static const uint32_t vk_to_gen_compare_op[] = {
+   [VK_COMPARE_OP_NEVER]                        = COMPAREFUNCTION_NEVER,
+   [VK_COMPARE_OP_LESS]                         = COMPAREFUNCTION_LESS,
+   [VK_COMPARE_OP_EQUAL]                        = COMPAREFUNCTION_EQUAL,
+   [VK_COMPARE_OP_LESS_EQUAL]                   = COMPAREFUNCTION_LEQUAL,
+   [VK_COMPARE_OP_GREATER]                      = COMPAREFUNCTION_GREATER,
+   [VK_COMPARE_OP_NOT_EQUAL]                    = COMPAREFUNCTION_NOTEQUAL,
+   [VK_COMPARE_OP_GREATER_EQUAL]                = COMPAREFUNCTION_GEQUAL,
+   [VK_COMPARE_OP_ALWAYS]                       = COMPAREFUNCTION_ALWAYS,
+};
+
+static const uint32_t vk_to_gen_stencil_op[] = {
+   [VK_STENCIL_OP_KEEP]                         = 0,
+   [VK_STENCIL_OP_ZERO]                         = 0,
+   [VK_STENCIL_OP_REPLACE]                      = 0,
+   [VK_STENCIL_OP_INC_CLAMP]                    = 0,
+   [VK_STENCIL_OP_DEC_CLAMP]                    = 0,
+   [VK_STENCIL_OP_INVERT]                       = 0,
+   [VK_STENCIL_OP_INC_WRAP]                     = 0,
+   [VK_STENCIL_OP_DEC_WRAP]                     = 0
+};
+
+static void
+emit_ds_state(struct anv_pipeline *pipeline, VkPipelineDsStateCreateInfo *info)
+{
+   if (info == NULL) {
+      /* We're going to OR this together with the dynamic state.  We need
+       * to make sure it's initialized to something useful.
+       */
+      memset(pipeline->state_wm_depth_stencil, 0,
+             sizeof(pipeline->state_wm_depth_stencil));
+      return;
+   }
+
+   /* bool32_t depthBoundsEnable;          // optional (depth_bounds_test) */
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      .DepthTestEnable = info->depthTestEnable,
+      .DepthBufferWriteEnable = info->depthWriteEnable,
+      .DepthTestFunction = vk_to_gen_compare_op[info->depthCompareOp],
+      .DoubleSidedStencilEnable = true,
+
+      .StencilTestEnable = info->stencilTestEnable,
+      .StencilFailOp = vk_to_gen_stencil_op[info->front.stencilFailOp],
+      .StencilPassDepthPassOp = vk_to_gen_stencil_op[info->front.stencilPassOp],
+      .StencilPassDepthFailOp = vk_to_gen_stencil_op[info->front.stencilDepthFailOp],
+      .StencilTestFunction = vk_to_gen_compare_op[info->front.stencilCompareOp],
+      .BackfaceStencilFailOp = vk_to_gen_stencil_op[info->back.stencilFailOp],
+      .BackfaceStencilPassDepthPassOp = vk_to_gen_stencil_op[info->back.stencilPassOp],
+      .BackfaceStencilPassDepthFailOp =vk_to_gen_stencil_op[info->back.stencilDepthFailOp],
+      .BackfaceStencilTestFunction = vk_to_gen_compare_op[info->back.stencilCompareOp],
+   };
+
+   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)
@@ -222,6 +377,21 @@ VkResult VKAPI vkCreateGraphicsPipeline(
    return anv_pipeline_create(device, pCreateInfo, NULL, pPipeline);
 }
 
+static void
+anv_pipeline_destroy(struct anv_device *device,
+                     struct anv_object *object,
+                     VkObjectType obj_type)
+{
+   struct anv_pipeline *pipeline = (struct anv_pipeline*) object;
+
+   assert(obj_type == VK_OBJECT_TYPE_PIPELINE);
+
+   anv_compiler_free(pipeline);
+   anv_reloc_list_finish(&pipeline->batch.relocs, pipeline->device);
+   anv_state_stream_finish(&pipeline->program_stream);
+   anv_state_pool_free(&device->dynamic_state_pool, pipeline->blend_state);
+   anv_device_free(pipeline->device, pipeline);
+}
 
 VkResult
 anv_pipeline_create(
@@ -234,9 +404,11 @@ anv_pipeline_create(
    struct anv_pipeline *pipeline;
    const struct anv_common *common;
    VkPipelineShaderStageCreateInfo *shader_create_info;
-   VkPipelineIaStateCreateInfo *ia_info;
-   VkPipelineRsStateCreateInfo *rs_info;
-   VkPipelineVertexInputCreateInfo *vi_info;
+   VkPipelineIaStateCreateInfo *ia_info = NULL;
+   VkPipelineRsStateCreateInfo *rs_info = NULL;
+   VkPipelineDsStateCreateInfo *ds_info = NULL;
+   VkPipelineCbStateCreateInfo *cb_info = NULL;
+   VkPipelineVertexInputCreateInfo *vi_info = NULL;
    VkResult result;
    uint32_t offset, length;
 
@@ -247,12 +419,21 @@ anv_pipeline_create(
    if (pipeline == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
+   pipeline->base.destructor = anv_pipeline_destroy;
    pipeline->device = device;
    pipeline->layout = (struct anv_pipeline_layout *) pCreateInfo->layout;
    memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
-   result = anv_batch_init(&pipeline->batch, device);
-   if (result != VK_SUCCESS)
-      goto fail;
+
+   result = anv_reloc_list_init(&pipeline->batch.relocs, device);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+   pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
+   pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
 
    for (common = pCreateInfo->pNext; common; common = common->pNext) {
       switch (common->sType) {
@@ -263,14 +444,23 @@ anv_pipeline_create(
          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] =
@@ -292,13 +482,42 @@ anv_pipeline_create(
    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);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_STATISTICS,
+                   .StatisticsEnable = true);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_HS, .Enable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_TE, .TEEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_DS, .FunctionEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
+                  .ConstantBufferOffset = 0,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
+                  .ConstantBufferOffset = 4,
+                  .ConstantBufferSize = 4);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
+                  .ConstantBufferOffset = 8,
+                  .ConstantBufferSize = 4);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM_CHROMAKEY,
+                  .ChromaKeyKillEnable = false);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SBE_SWIZ);
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_CLIP,
                   .ClipEnable = true,
-                  .ViewportXYClipTestEnable = !(extra && extra->disable_viewport));
+                  .ViewportXYClipTestEnable = !(extra && extra->disable_viewport),
+                  .MinimumPointWidth = 0.125,
+                  .MaximumPointWidth = 255.875);
 
    anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM,
                   .StatisticsEnable = true,
@@ -354,8 +573,8 @@ anv_pipeline_create(
                      .BindingTableEntryCount = 0,
                      .ExpectedVertexCount = pipeline->gs_vertex_count,
                         
-                     .PerThreadScratchSpace = 0,
-                     .ScratchSpaceBasePointer = 0,
+                     .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_GEOMETRY],
+                     .PerThreadScratchSpace = ffs(gs_prog_data->base.base.total_scratch / 2048),
 
                      .OutputVertexSize = gs_prog_data->output_vertex_size_hwords * 2 - 1,
                      .OutputTopology = gs_prog_data->output_topology,
@@ -381,8 +600,6 @@ anv_pipeline_create(
                      .VertexURBEntryOutputReadOffset = offset,
                      .VertexURBEntryOutputLength = length);
 
-   //trp_generate_blend_hw_cmds(batch, pipeline);
-
    const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
    /* Skip the VUE header and position slots */
    offset = 1;
@@ -411,11 +628,8 @@ anv_pipeline_create(
                      .AccessesUAV = false,
                      .SoftwareExceptionEnable = false,
 
-                     /* FIXME: pointer needs to be assigned outside as it aliases
-                      * PerThreadScratchSpace.
-                      */
-                     .ScratchSpaceBasePointer = 0,
-                     .PerThreadScratchSpace = 0,
+                     .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_VERTEX],
+                     .PerThreadScratchSpace = ffs(vue_prog_data->base.total_scratch / 2048),
 
                      .DispatchGRFStartRegisterForURBData =
                      vue_prog_data->base.dispatch_grf_start_reg,
@@ -459,8 +673,8 @@ anv_pipeline_create(
                   .VectorMaskEnable = true,
                   .SamplerCount = 1,
 
-                  .ScratchSpaceBasePointer = 0,
-                  .PerThreadScratchSpace = 0,
+                  .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_FRAGMENT],
+                  .PerThreadScratchSpace = ffs(wm_prog_data->base.total_scratch / 2048),
                   
                   .MaximumNumberofThreadsPerPSD = 64 - 2,
                   .PositionXYOffsetSelect = wm_prog_data->uses_pos_offset ?
@@ -488,25 +702,10 @@ anv_pipeline_create(
 
    *pPipeline = (VkPipeline) pipeline;
 
-   return VK_SUCCESS;
-
- fail:
-   anv_device_free(device, pipeline);
-   
-   return result;
-}
-
-VkResult
-anv_pipeline_destroy(struct anv_pipeline *pipeline)
-{
-   anv_compiler_free(pipeline);
-   anv_batch_finish(&pipeline->batch, pipeline->device);
-   anv_device_free(pipeline->device, pipeline);
-
    return VK_SUCCESS;
 }
 
-VkResult VKAPI vkCreateGraphicsPipelineDerivative(
+VkResult anv_CreateGraphicsPipelineDerivative(
     VkDevice                                    device,
     const VkGraphicsPipelineCreateInfo*         pCreateInfo,
     VkPipeline                                  basePipeline,
@@ -515,15 +714,79 @@ VkResult VKAPI vkCreateGraphicsPipelineDerivative(
    stub_return(VK_UNSUPPORTED);
 }
 
-VkResult VKAPI vkCreateComputePipeline(
-    VkDevice                                    device,
+VkResult anv_CreateComputePipeline(
+    VkDevice                                    _device,
     const VkComputePipelineCreateInfo*          pCreateInfo,
     VkPipeline*                                 pPipeline)
 {
-   stub_return(VK_UNSUPPORTED);
+   struct anv_device *device = (struct anv_device *) _device;
+   struct anv_pipeline *pipeline;
+   VkResult result;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
+
+   pipeline = anv_device_alloc(device, sizeof(*pipeline), 8,
+                               VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (pipeline == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   pipeline->base.destructor = anv_pipeline_destroy;
+   pipeline->device = device;
+   pipeline->layout = (struct anv_pipeline_layout *) pCreateInfo->layout;
+
+   result = anv_reloc_list_init(&pipeline->batch.relocs, device);
+   if (result != VK_SUCCESS) {
+      anv_device_free(device, pipeline);
+      return result;
+   }
+   pipeline->batch.next = pipeline->batch.start = pipeline->batch_data;
+   pipeline->batch.end = pipeline->batch.start + sizeof(pipeline->batch_data);
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+
+   pipeline->shaders[VK_SHADER_STAGE_COMPUTE] =
+      (struct anv_shader *) pCreateInfo->cs.shader;
+
+   pipeline->use_repclear = false;
+
+   anv_compiler_run(device->compiler, pipeline);
+
+   const struct brw_cs_prog_data *cs_prog_data = &pipeline->cs_prog_data;
+
+   anv_batch_emit(&pipeline->batch, GEN8_MEDIA_VFE_STATE,
+                  .ScratchSpaceBasePointer = pipeline->scratch_start[VK_SHADER_STAGE_FRAGMENT],
+                  .PerThreadScratchSpace = ffs(cs_prog_data->base.total_scratch / 2048),
+                  .ScratchSpaceBasePointerHigh = 0,
+                  .StackSize = 0,
+
+                  .MaximumNumberofThreads = device->info.max_cs_threads - 1,
+                  .NumberofURBEntries = 2,
+                  .ResetGatewayTimer = true,
+                  .BypassGatewayControl = true,
+                  .URBEntryAllocationSize = 2,
+                  .CURBEAllocationSize = 0);
+
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   uint32_t group_size = prog_data->local_size[0] *
+      prog_data->local_size[1] * prog_data->local_size[2];
+   pipeline->cs_thread_width_max = DIV_ROUND_UP(group_size, prog_data->simd_size);
+   uint32_t remainder = group_size & (prog_data->simd_size - 1);
+
+   if (remainder > 0)
+      pipeline->cs_right_mask = ~0u >> (32 - remainder);
+   else
+      pipeline->cs_right_mask = ~0u >> (32 - prog_data->simd_size);
+
+
+   *pPipeline = (VkPipeline) pipeline;
+
+   return VK_SUCCESS;
 }
 
-VkResult VKAPI vkStorePipeline(
+VkResult anv_StorePipeline(
     VkDevice                                    device,
     VkPipeline                                  pipeline,
     size_t*                                     pDataSize,
@@ -532,7 +795,7 @@ VkResult VKAPI vkStorePipeline(
    stub_return(VK_UNSUPPORTED);
 }
 
-VkResult VKAPI vkLoadPipeline(
+VkResult anv_LoadPipeline(
     VkDevice                                    device,
     size_t                                      dataSize,
     const void*                                 pData,
@@ -541,7 +804,7 @@ VkResult VKAPI vkLoadPipeline(
    stub_return(VK_UNSUPPORTED);
 }
 
-VkResult VKAPI vkLoadPipelineDerivative(
+VkResult anv_LoadPipelineDerivative(
     VkDevice                                    device,
     size_t                                      dataSize,
     const void*                                 pData,
@@ -553,88 +816,45 @@ VkResult VKAPI vkLoadPipelineDerivative(
 
 // Pipeline layout functions
 
-VkResult VKAPI vkCreatePipelineLayout(
+VkResult anv_CreatePipelineLayout(
     VkDevice                                    _device,
     const VkPipelineLayoutCreateInfo*           pCreateInfo,
     VkPipelineLayout*                           pPipelineLayout)
 {
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_pipeline_layout *layout;
-   struct anv_pipeline_layout_entry *sampler_entry, *surface_entry;
-   uint32_t sampler_total, surface_total;
-   size_t size;
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO);
-   
-   sampler_total = 0;
-   surface_total = 0;
-   for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
-      struct anv_descriptor_set_layout *set_layout =
-         (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
-      for (uint32_t j = 0; j < set_layout->count; j++) {
-         sampler_total += set_layout->sampler_total;
-         surface_total += set_layout->surface_total;
-      }
-   }
 
-   size = sizeof(*layout) +
-      (sampler_total + surface_total) * sizeof(layout->entries[0]);
-   layout = anv_device_alloc(device, size, 8,
+   layout = anv_device_alloc(device, sizeof(*layout), 8,
                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
    if (layout == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   sampler_entry = layout->entries;
-   surface_entry = layout->entries + sampler_total;
+   layout->num_sets = pCreateInfo->descriptorSetCount;
+
+   uint32_t surface_start[VK_NUM_SHADER_STAGE] = { 0, };
+   uint32_t sampler_start[VK_NUM_SHADER_STAGE] = { 0, };
+
    for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
-      layout->stage[s].sampler_entries = sampler_entry;
-      layout->stage[s].surface_entries = surface_entry;
-
-      for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
-         struct anv_descriptor_set_layout *set_layout =
-            (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
-         for (uint32_t j = 0; j < set_layout->count; j++) {
-            if (set_layout->bindings[j].mask & (1 << s)) {
-               switch (set_layout->bindings[j].type) {
-               case VK_DESCRIPTOR_TYPE_SAMPLER:
-                  sampler_entry->type = set_layout->bindings[j].type;
-                  sampler_entry->set = i;
-                  sampler_entry->index = j;
-                  sampler_entry++;
-                  break;
-
-               case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
-                  sampler_entry->type = set_layout->bindings[j].type;
-                  sampler_entry->set = i;
-                  sampler_entry->index = j;
-                  sampler_entry++;
-                  /* fall through */
-
-               case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
-               case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
-               case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
-               case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
-               case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
-               case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
-               case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
-               case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
-                  surface_entry->type = set_layout->bindings[j].type;
-                  surface_entry->set = i;
-                  surface_entry->index = j;
-                  surface_entry++;
-                  break;
-
-               default:
-                  break;
-               }
-            }
-         }
-      }
+      layout->stage[s].surface_count = 0;
+      layout->stage[s].sampler_count = 0;
+   }
 
-      layout->stage[s].sampler_count =
-         sampler_entry - layout->stage[s].sampler_entries;
-      layout->stage[s].surface_count =
-         surface_entry - layout->stage[s].surface_entries;
+   for (uint32_t i = 0; i < pCreateInfo->descriptorSetCount; i++) {
+      struct anv_descriptor_set_layout *set_layout =
+         (struct anv_descriptor_set_layout *) pCreateInfo->pSetLayouts[i];
+
+      layout->set[i].layout = set_layout;
+      for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
+         layout->set[i].surface_start[s] = surface_start[s];
+         surface_start[s] += set_layout->stage[s].surface_count;
+         layout->set[i].sampler_start[s] = sampler_start[s];
+         sampler_start[s] += set_layout->stage[s].sampler_count;
+
+         layout->stage[s].surface_count += set_layout->stage[s].surface_count;
+         layout->stage[s].sampler_count += set_layout->stage[s].sampler_count;
+      }
    }
 
    *pPipelineLayout = (VkPipelineLayout) layout;