vk: Reorder gen8 specific code into three new files
authorKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Mon, 17 Aug 2015 23:17:07 +0000 (16:17 -0700)
committerKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Mon, 24 Aug 2015 20:45:40 +0000 (13:45 -0700)
We'll organize gen specific code in three files per gen: pipeline,
cmd_buffer and state, eg:

    gen8_cmd_buffer.c
    gen8_pipeline.c
    gen8_state.c

where gen8_cmd_buffer.c holds all vkCmd* entry points, gne8_pipeline.c
all gen specific code related to pipeline building and remaining state
code (sampler, surface state, dynamic state) in gen8_state.c.

Signed-off-by: Kristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
src/vulkan/Makefile.am
src/vulkan/anv_cmd_buffer.c
src/vulkan/anv_gen8.c [deleted file]
src/vulkan/anv_meta.c
src/vulkan/anv_private.h
src/vulkan/gen8_cmd_buffer.c [new file with mode: 0644]
src/vulkan/gen8_pipeline.c [new file with mode: 0644]
src/vulkan/gen8_state.c [new file with mode: 0644]

index 6c833d84753a009906c95e7a0774022dfadedcf1..2359ffeeff12f3b39eb31853dcceb41a4ab5a15c 100644 (file)
@@ -73,7 +73,9 @@ VULKAN_SOURCES =                                        \
        anv_query.c                                     \
        anv_util.c                                      \
        anv_x11.c                                       \
-       anv_gen8.c
+       gen8_state.c                                    \
+       gen8_cmd_buffer.c                               \
+       gen8_pipeline.c
 
 libvulkan_la_SOURCES =                                  \
        $(VULKAN_SOURCES)                               \
index b874ba76738c7d3f2ca48d5a4788a01f24d3df0e..84e690321475ecf0b420fbcab1167d56f38b70d4 100644 (file)
@@ -320,9 +320,9 @@ void anv_CmdBindVertexBuffers(
    }
 }
 
-static VkResult
-cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
-                              unsigned stage, struct anv_state *bt_state)
+VkResult
+anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                  unsigned stage, struct anv_state *bt_state)
 {
    struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
    struct anv_subpass *subpass = cmd_buffer->state.subpass;
@@ -440,9 +440,9 @@ cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
    return VK_SUCCESS;
 }
 
-static VkResult
-cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
-                         unsigned stage, struct anv_state *state)
+VkResult
+anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
+                             unsigned stage, struct anv_state *state)
 {
    struct anv_pipeline_layout *layout;
    uint32_t sampler_count;
@@ -491,10 +491,10 @@ flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
    struct anv_state surfaces = { 0, }, samplers = { 0, };
    VkResult result;
 
-   result = cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
+   result = anv_cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
    if (result != VK_SUCCESS)
       return result;
-   result = cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
+   result = anv_cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
    if (result != VK_SUCCESS)
       return result;
 
@@ -533,8 +533,8 @@ flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
    return VK_SUCCESS;
 }
 
-static void
-flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
+void
+anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
 {
    uint32_t s, dirty = cmd_buffer->state.descriptors_dirty &
                        cmd_buffer->state.pipeline->active_stages;
@@ -569,7 +569,7 @@ flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
    cmd_buffer->state.descriptors_dirty &= ~cmd_buffer->state.pipeline->active_stages;
 }
 
-static struct anv_state
+struct anv_state
 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
                              uint32_t *a, uint32_t dwords, uint32_t alignment)
 {
@@ -584,7 +584,7 @@ anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
    return state;
 }
 
-static struct anv_state
+struct anv_state
 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
                              uint32_t *a, uint32_t *b,
                              uint32_t dwords, uint32_t alignment)
@@ -603,363 +603,11 @@ anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
    return state;
 }
 
-static VkResult
-flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_device *device = cmd_buffer->device;
-   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
-   struct anv_state surfaces = { 0, }, samplers = { 0, };
-   VkResult result;
-
-   result = cmd_buffer_emit_samplers(cmd_buffer,
-                                     VK_SHADER_STAGE_COMPUTE, &samplers);
-   if (result != VK_SUCCESS)
-      return result;
-   result = cmd_buffer_emit_binding_table(cmd_buffer,
-                                          VK_SHADER_STAGE_COMPUTE, &surfaces);
-   if (result != VK_SUCCESS)
-      return result;
-
-   struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
-      .KernelStartPointer = pipeline->cs_simd,
-      .KernelStartPointerHigh = 0,
-      .BindingTablePointer = surfaces.offset,
-      .BindingTableEntryCount = 0,
-      .SamplerStatePointer = samplers.offset,
-      .SamplerCount = 0,
-      .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
-   };
-
-   uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
-   struct anv_state state =
-      anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
-
-   GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
-                  .InterfaceDescriptorTotalLength = size,
-                  .InterfaceDescriptorDataStartAddress = state.offset);
-
-   return VK_SUCCESS;
-}
-
-static void
-anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
-   VkResult result;
-
-   assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
-
-   if (cmd_buffer->state.current_pipeline != GPGPU) {
-      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
-                     .PipelineSelection = GPGPU);
-      cmd_buffer->state.current_pipeline = GPGPU;
-   }
-
-   if (cmd_buffer->state.compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
-      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
-
-   if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
-       (cmd_buffer->state.compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)) {
-      result = flush_compute_descriptor_set(cmd_buffer);
-      assert(result == VK_SUCCESS);
-      cmd_buffer->state.descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
-   }
-
-   cmd_buffer->state.compute_dirty = 0;
-}
-
-static void
-anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
-   uint32_t *p;
-
-   uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
-
-   assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
-
-   if (cmd_buffer->state.current_pipeline != _3D) {
-      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
-                     .PipelineSelection = _3D);
-      cmd_buffer->state.current_pipeline = _3D;
-   }
-
-   if (vb_emit) {
-      const uint32_t num_buffers = __builtin_popcount(vb_emit);
-      const uint32_t num_dwords = 1 + num_buffers * 4;
-
-      p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
-                          GEN8_3DSTATE_VERTEX_BUFFERS);
-      uint32_t vb, i = 0;
-      for_each_bit(vb, vb_emit) {
-         struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
-         uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
-
-         struct GEN8_VERTEX_BUFFER_STATE state = {
-            .VertexBufferIndex = vb,
-            .MemoryObjectControlState = GEN8_MOCS,
-            .AddressModifyEnable = true,
-            .BufferPitch = pipeline->binding_stride[vb],
-            .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
-            .BufferSize = buffer->size - offset
-         };
-
-         GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
-         i++;
-      }
-   }
-
-   if (cmd_buffer->state.dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY) {
-      /* If somebody compiled a pipeline after starting a command buffer the
-       * scratch bo may have grown since we started this cmd buffer (and
-       * emitted STATE_BASE_ADDRESS).  If we're binding that pipeline now,
-       * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
-      if (cmd_buffer->state.scratch_size < pipeline->total_scratch)
-         anv_cmd_buffer_emit_state_base_address(cmd_buffer);
-
-      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
-   }
-
-   if (cmd_buffer->state.descriptors_dirty)
-      flush_descriptor_sets(cmd_buffer);
-
-   if (cmd_buffer->state.dirty & ANV_CMD_BUFFER_VP_DIRTY) {
-      struct anv_dynamic_vp_state *vp_state = cmd_buffer->state.vp_state;
-      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
-                     .ScissorRectPointer = vp_state->scissor.offset);
-      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
-                     .CCViewportPointer = vp_state->cc_vp.offset);
-      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
-                     .SFClipViewportPointer = vp_state->sf_clip_vp.offset);
-   }
-
-   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
-                                  ANV_CMD_BUFFER_RS_DIRTY)) {
-      anv_batch_emit_merge(&cmd_buffer->batch,
-                           cmd_buffer->state.rs_state->state_sf,
-                           pipeline->state_sf);
-      anv_batch_emit_merge(&cmd_buffer->batch,
-                           cmd_buffer->state.rs_state->state_raster,
-                           pipeline->state_raster);
-   }
-
-   if (cmd_buffer->state.ds_state &&
-       (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
-                                   ANV_CMD_BUFFER_DS_DIRTY))) {
-      anv_batch_emit_merge(&cmd_buffer->batch,
-                           cmd_buffer->state.ds_state->state_wm_depth_stencil,
-                           pipeline->state_wm_depth_stencil);
-   }
-
-   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_CB_DIRTY |
-                                  ANV_CMD_BUFFER_DS_DIRTY)) {
-      struct anv_state state;
-      if (cmd_buffer->state.ds_state == NULL)
-         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
-                                             cmd_buffer->state.cb_state->state_color_calc,
-                                             GEN8_COLOR_CALC_STATE_length, 64);
-      else if (cmd_buffer->state.cb_state == NULL)
-         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
-                                             cmd_buffer->state.ds_state->state_color_calc,
-                                             GEN8_COLOR_CALC_STATE_length, 64);
-      else
-         state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
-                                              cmd_buffer->state.ds_state->state_color_calc,
-                                              cmd_buffer->state.cb_state->state_color_calc,
-                                              GEN8_COLOR_CALC_STATE_length, 64);
-
-      anv_batch_emit(&cmd_buffer->batch,
-                     GEN8_3DSTATE_CC_STATE_POINTERS,
-                     .ColorCalcStatePointer = state.offset,
-                     .ColorCalcStatePointerValid = true);
-   }
-
-   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
-                                  ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY)) {
-      anv_batch_emit_merge(&cmd_buffer->batch,
-                           cmd_buffer->state.state_vf, pipeline->state_vf);
-   }
-
-   cmd_buffer->state.vb_dirty &= ~vb_emit;
-   cmd_buffer->state.dirty = 0;
-}
-
-void anv_CmdDraw(
-    VkCmdBuffer                                 cmdBuffer,
-    uint32_t                                    firstVertex,
-    uint32_t                                    vertexCount,
-    uint32_t                                    firstInstance,
-    uint32_t                                    instanceCount)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-
-   anv_cmd_buffer_flush_state(cmd_buffer);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
-                  .VertexAccessType = SEQUENTIAL,
-                  .VertexCountPerInstance = vertexCount,
-                  .StartVertexLocation = firstVertex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = 0);
-}
-
-void anv_CmdDrawIndexed(
-    VkCmdBuffer                                 cmdBuffer,
-    uint32_t                                    firstIndex,
-    uint32_t                                    indexCount,
-    int32_t                                     vertexOffset,
-    uint32_t                                    firstInstance,
-    uint32_t                                    instanceCount)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-
-   anv_cmd_buffer_flush_state(cmd_buffer);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
-                  .VertexAccessType = RANDOM,
-                  .VertexCountPerInstance = indexCount,
-                  .StartVertexLocation = firstIndex,
-                  .InstanceCount = instanceCount,
-                  .StartInstanceLocation = firstInstance,
-                  .BaseVertexLocation = vertexOffset);
-}
-
-static void
-anv_batch_lrm(struct anv_batch *batch,
-              uint32_t reg, struct anv_bo *bo, uint32_t offset)
-{
-   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
-                  .RegisterAddress = reg,
-                  .MemoryAddress = { bo, offset });
-}
-
-static void
-anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
-{
-   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
-                  .RegisterOffset = reg,
-                  .DataDWord = imm);
-}
-
-/* Auto-Draw / Indirect Registers */
-#define GEN7_3DPRIM_END_OFFSET          0x2420
-#define GEN7_3DPRIM_START_VERTEX        0x2430
-#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
-#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
-#define GEN7_3DPRIM_START_INSTANCE      0x243C
-#define GEN7_3DPRIM_BASE_VERTEX         0x2440
-
-void anv_CmdDrawIndirect(
-    VkCmdBuffer                                 cmdBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    count,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   anv_cmd_buffer_flush_state(cmd_buffer);
-
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
-   anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = SEQUENTIAL);
-}
-
-void anv_CmdDrawIndexedIndirect(
-    VkCmdBuffer                                 cmdBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    uint32_t                                    count,
-    uint32_t                                    stride)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   anv_cmd_buffer_flush_state(cmd_buffer);
-
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
-   anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
-                  .IndirectParameterEnable = true,
-                  .VertexAccessType = RANDOM);
-}
-
-void anv_CmdDispatch(
-    VkCmdBuffer                                 cmdBuffer,
-    uint32_t                                    x,
-    uint32_t                                    y,
-    uint32_t                                    z)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
-   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
-
-   anv_cmd_buffer_flush_compute_state(cmd_buffer);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
-                  .SIMDSize = prog_data->simd_size / 16,
-                  .ThreadDepthCounterMaximum = 0,
-                  .ThreadHeightCounterMaximum = 0,
-                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
-                  .ThreadGroupIDXDimension = x,
-                  .ThreadGroupIDYDimension = y,
-                  .ThreadGroupIDZDimension = z,
-                  .RightExecutionMask = pipeline->cs_right_mask,
-                  .BottomExecutionMask = 0xffffffff);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
-}
-
-#define GPGPU_DISPATCHDIMX 0x2500
-#define GPGPU_DISPATCHDIMY 0x2504
-#define GPGPU_DISPATCHDIMZ 0x2508
-
-void anv_CmdDispatchIndirect(
-    VkCmdBuffer                                 cmdBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset)
+void
+anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_subpass *subpass)
 {
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
-   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
-   struct anv_bo *bo = buffer->bo;
-   uint32_t bo_offset = buffer->offset + offset;
-
-   anv_cmd_buffer_flush_compute_state(cmd_buffer);
-
-   anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
-   anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
-   anv_batch_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
-                  .IndirectParameterEnable = true,
-                  .SIMDSize = prog_data->simd_size / 16,
-                  .ThreadDepthCounterMaximum = 0,
-                  .ThreadHeightCounterMaximum = 0,
-                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
-                  .RightExecutionMask = pipeline->cs_right_mask,
-                  .BottomExecutionMask = 0xffffffff);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
+   gen8_cmd_buffer_begin_subpass(cmd_buffer, subpass);
 }
 
 void anv_CmdSetEvent(
@@ -1139,131 +787,6 @@ void anv_CmdPushConstants(
    stub();
 }
 
-static void
-anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_subpass *subpass = cmd_buffer->state.subpass;
-   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
-   const struct anv_depth_stencil_view *view;
-
-   static const struct anv_depth_stencil_view null_view =
-      { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
-
-   if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
-      const struct anv_attachment_view *aview =
-         fb->attachments[subpass->depth_stencil_attachment];
-      assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL);
-      view = (const struct anv_depth_stencil_view *)aview;
-   } else {
-      view = &null_view;
-   }
-
-   /* FIXME: Implement the PMA stall W/A */
-   /* FIXME: Width and Height are wrong */
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
-                  .SurfaceType = SURFTYPE_2D,
-                  .DepthWriteEnable = view->depth_stride > 0,
-                  .StencilWriteEnable = view->stencil_stride > 0,
-                  .HierarchicalDepthBufferEnable = false,
-                  .SurfaceFormat = view->depth_format,
-                  .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
-                  .SurfaceBaseAddress = { view->bo,  view->depth_offset },
-                  .Height = cmd_buffer->state.framebuffer->height - 1,
-                  .Width = cmd_buffer->state.framebuffer->width - 1,
-                  .LOD = 0,
-                  .Depth = 1 - 1,
-                  .MinimumArrayElement = 0,
-                  .DepthBufferObjectControlState = GEN8_MOCS,
-                  .RenderTargetViewExtent = 1 - 1,
-                  .SurfaceQPitch = view->depth_qpitch >> 2);
-
-   /* Disable hierarchial depth buffers. */
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
-                  .StencilBufferEnable = view->stencil_stride > 0,
-                  .StencilBufferObjectControlState = GEN8_MOCS,
-                  .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
-                  .SurfaceBaseAddress = { view->bo, view->stencil_offset },
-                  .SurfaceQPitch = view->stencil_qpitch >> 2);
-
-   /* Clear the clear params. */
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
-}
-
-void
-anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
-                             struct anv_subpass *subpass)
-{
-   cmd_buffer->state.subpass = subpass;
-
-   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
-
-   anv_cmd_buffer_emit_depth_stencil(cmd_buffer);
-}
-
-void anv_CmdBeginRenderPass(
-    VkCmdBuffer                                 cmdBuffer,
-    const VkRenderPassBeginInfo*                pRenderPassBegin,
-    VkRenderPassContents                        contents)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
-   ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
-
-   cmd_buffer->state.framebuffer = framebuffer;
-   cmd_buffer->state.pass = pass;
-
-   const VkRect2D *render_area = &pRenderPassBegin->renderArea;
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
-                  .ClippedDrawingRectangleYMin = render_area->offset.y,
-                  .ClippedDrawingRectangleXMin = render_area->offset.x,
-                  .ClippedDrawingRectangleYMax =
-                     render_area->offset.y + render_area->extent.height - 1,
-                  .ClippedDrawingRectangleXMax =
-                     render_area->offset.x + render_area->extent.width - 1,
-                  .DrawingRectangleOriginY = 0,
-                  .DrawingRectangleOriginX = 0);
-
-   anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
-                                    pRenderPassBegin->pAttachmentClearValues);
-
-   anv_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
-}
-
-void anv_CmdNextSubpass(
-    VkCmdBuffer                                 cmdBuffer,
-    VkRenderPassContents                        contents)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-
-   assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
-
-   anv_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
-}
-
-void anv_CmdEndRenderPass(
-    VkCmdBuffer                                 cmdBuffer)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-
-   /* Emit a flushing pipe control at the end of a pass.  This is kind of a
-    * hack but it ensures that render targets always actually get written.
-    * Eventually, we should do flushing based on image format transitions
-    * or something of that nature.
-    */
-   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
-                  .PostSyncOperation = NoWrite,
-                  .RenderTargetCacheFlushEnable = true,
-                  .InstructionCacheInvalidateEnable = true,
-                  .DepthCacheFlushEnable = true,
-                  .VFCacheInvalidationEnable = true,
-                  .TextureCacheInvalidationEnable = true,
-                  .CommandStreamerStallEnable = true);
-}
-
 void anv_CmdExecuteCommands(
     VkCmdBuffer                                 cmdBuffer,
     uint32_t                                    cmdBuffersCount,
diff --git a/src/vulkan/anv_gen8.c b/src/vulkan/anv_gen8.c
deleted file mode 100644 (file)
index 95afaad..0000000
+++ /dev/null
@@ -1,1253 +0,0 @@
-/*
- * Copyright © 2015 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdbool.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include "anv_private.h"
-
-VkResult gen8_CreateDynamicRasterState(
-    VkDevice                                    _device,
-    const VkDynamicRasterStateCreateInfo*       pCreateInfo,
-    VkDynamicRasterState*                       pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_rs_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   struct GEN8_3DSTATE_SF sf = {
-      GEN8_3DSTATE_SF_header,
-      .LineWidth = pCreateInfo->lineWidth,
-   };
-
-   GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
-
-   bool enable_bias = pCreateInfo->depthBias != 0.0f ||
-      pCreateInfo->slopeScaledDepthBias != 0.0f;
-   struct GEN8_3DSTATE_RASTER raster = {
-      .GlobalDepthOffsetEnableSolid = enable_bias,
-      .GlobalDepthOffsetEnableWireframe = enable_bias,
-      .GlobalDepthOffsetEnablePoint = enable_bias,
-      .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
-      .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
-      .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
-   };
-
-   GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
-
-   *pState = anv_dynamic_rs_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-void
-gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
-                               uint32_t offset, uint32_t range)
-{
-   /* This assumes RGBA float format. */
-   uint32_t stride = 4;
-   uint32_t num_elements = range / stride;
-
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = SURFTYPE_BUFFER,
-      .SurfaceArray = false,
-      .SurfaceFormat = format->surface_format,
-      .SurfaceVerticalAlignment = VALIGN4,
-      .SurfaceHorizontalAlignment = HALIGN4,
-      .TileMode = LINEAR,
-      .VerticalLineStride = 0,
-      .VerticalLineStrideOffset = 0,
-      .SamplerL2BypassModeDisable = true,
-      .RenderCacheReadWriteMode = WriteOnlyCache,
-      .MemoryObjectControlState = GEN8_MOCS,
-      .BaseMipLevel = 0.0,
-      .SurfaceQPitch = 0,
-      .Height = (num_elements >> 7) & 0x3fff,
-      .Width = num_elements & 0x7f,
-      .Depth = (num_elements >> 21) & 0x3f,
-      .SurfacePitch = stride - 1,
-      .MinimumArrayElement = 0,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
-      .SurfaceMinLOD = 0,
-      .MIPCountLOD = 0,
-      .AuxiliarySurfaceMode = AUX_NONE,
-      .RedClearColor = 0,
-      .GreenClearColor = 0,
-      .BlueClearColor = 0,
-      .AlphaClearColor = 0,
-      .ShaderChannelSelectRed = SCS_RED,
-      .ShaderChannelSelectGreen = SCS_GREEN,
-      .ShaderChannelSelectBlue = SCS_BLUE,
-      .ShaderChannelSelectAlpha = SCS_ALPHA,
-      .ResourceMinLOD = 0.0,
-      /* FIXME: We assume that the image must be bound at this time. */
-      .SurfaceBaseAddress = { NULL, offset },
-   };
-
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
-}
-
-VkResult gen8_CreateBufferView(
-    VkDevice                                    _device,
-    const VkBufferViewCreateInfo*               pCreateInfo,
-    VkBufferView*                               pView)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_buffer_view *view;
-   VkResult result;
-
-   result = anv_buffer_view_create(device, pCreateInfo, &view);
-   if (result != VK_SUCCESS)
-      return result;
-
-   const struct anv_format *format = 
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   gen8_fill_buffer_surface_state(view->view.surface_state.map, format,
-                                  view->view.offset, pCreateInfo->range);
-
-   *pView = anv_buffer_view_to_handle(view);
-
-   return VK_SUCCESS;
-}
-
-VkResult gen8_CreateSampler(
-    VkDevice                                    _device,
-    const VkSamplerCreateInfo*                  pCreateInfo,
-    VkSampler*                                  pSampler)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_sampler *sampler;
-   uint32_t mag_filter, min_filter, max_anisotropy;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
-
-   sampler = anv_device_alloc(device, sizeof(*sampler), 8,
-                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (!sampler)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   static const uint32_t vk_to_gen_tex_filter[] = {
-      [VK_TEX_FILTER_NEAREST]                   = MAPFILTER_NEAREST,
-      [VK_TEX_FILTER_LINEAR]                    = MAPFILTER_LINEAR
-   };
-
-   static const uint32_t vk_to_gen_mipmap_mode[] = {
-      [VK_TEX_MIPMAP_MODE_BASE]                 = MIPFILTER_NONE,
-      [VK_TEX_MIPMAP_MODE_NEAREST]              = MIPFILTER_NEAREST,
-      [VK_TEX_MIPMAP_MODE_LINEAR]               = MIPFILTER_LINEAR
-   };
-
-   static const uint32_t vk_to_gen_tex_address[] = {
-      [VK_TEX_ADDRESS_WRAP]                     = TCM_WRAP,
-      [VK_TEX_ADDRESS_MIRROR]                   = TCM_MIRROR,
-      [VK_TEX_ADDRESS_CLAMP]                    = TCM_CLAMP,
-      [VK_TEX_ADDRESS_MIRROR_ONCE]              = TCM_MIRROR_ONCE,
-      [VK_TEX_ADDRESS_CLAMP_BORDER]             = TCM_CLAMP_BORDER,
-   };
-
-   static const uint32_t vk_to_gen_compare_op[] = {
-      [VK_COMPARE_OP_NEVER]                     = PREFILTEROPNEVER,
-      [VK_COMPARE_OP_LESS]                      = PREFILTEROPLESS,
-      [VK_COMPARE_OP_EQUAL]                     = PREFILTEROPEQUAL,
-      [VK_COMPARE_OP_LESS_EQUAL]                = PREFILTEROPLEQUAL,
-      [VK_COMPARE_OP_GREATER]                   = PREFILTEROPGREATER,
-      [VK_COMPARE_OP_NOT_EQUAL]                 = PREFILTEROPNOTEQUAL,
-      [VK_COMPARE_OP_GREATER_EQUAL]             = PREFILTEROPGEQUAL,
-      [VK_COMPARE_OP_ALWAYS]                    = PREFILTEROPALWAYS,
-   };
-
-   if (pCreateInfo->maxAnisotropy > 1) {
-      mag_filter = MAPFILTER_ANISOTROPIC;
-      min_filter = MAPFILTER_ANISOTROPIC;
-      max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
-   } else {
-      mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
-      min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
-      max_anisotropy = RATIO21;
-   }
-
-   struct GEN8_SAMPLER_STATE sampler_state = {
-      .SamplerDisable = false,
-      .TextureBorderColorMode = DX10OGL,
-      .LODPreClampMode = 0,
-      .BaseMipLevel = 0.0,
-      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
-      .MagModeFilter = mag_filter,
-      .MinModeFilter = min_filter,
-      .TextureLODBias = pCreateInfo->mipLodBias * 256,
-      .AnisotropicAlgorithm = EWAApproximation,
-      .MinLOD = pCreateInfo->minLod,
-      .MaxLOD = pCreateInfo->maxLod,
-      .ChromaKeyEnable = 0,
-      .ChromaKeyIndex = 0,
-      .ChromaKeyMode = 0,
-      .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
-      .CubeSurfaceControlMode = 0,
-
-      .IndirectStatePointer =
-         device->border_colors.offset +
-         pCreateInfo->borderColor * sizeof(float) * 4,
-
-      .LODClampMagnificationMode = MIPNONE,
-      .MaximumAnisotropy = max_anisotropy,
-      .RAddressMinFilterRoundingEnable = 0,
-      .RAddressMagFilterRoundingEnable = 0,
-      .VAddressMinFilterRoundingEnable = 0,
-      .VAddressMagFilterRoundingEnable = 0,
-      .UAddressMinFilterRoundingEnable = 0,
-      .UAddressMagFilterRoundingEnable = 0,
-      .TrilinearFilterQuality = 0,
-      .NonnormalizedCoordinateEnable = 0,
-      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
-      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
-      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
-   };
-
-   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
-
-   *pSampler = anv_sampler_to_handle(sampler);
-
-   return VK_SUCCESS;
-}
-
-static void
-emit_vertex_input(struct anv_pipeline *pipeline,
-                  const VkPipelineVertexInputStateCreateInfo *info)
-{
-   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
-       * binding. Set up a map of which bindings step per instance, for
-       * reference by vertex element setup. */
-      switch (desc->stepRate) {
-      default:
-      case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
-         instancing_enable[desc->binding] = false;
-         break;
-      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
-         instancing_enable[desc->binding] = true;
-         break;
-      }
-   }
-
-   p = anv_batch_emitn(&pipeline->batch, num_dwords,
-                       GEN8_3DSTATE_VERTEX_ELEMENTS);
-
-   for (uint32_t i = 0; i < info->attributeCount; i++) {
-      const VkVertexInputAttributeDescription *desc =
-         &info->pVertexAttributeDescriptions[i];
-      const struct anv_format *format = anv_format_for_vk_format(desc->format);
-
-      struct GEN8_VERTEX_ELEMENT_STATE element = {
-         .VertexBufferIndex = desc->binding,
-         .Valid = true,
-         .SourceElementFormat = format->surface_format,
-         .EdgeFlagEnable = false,
-         .SourceElementOffset = desc->offsetInBytes,
-         .Component0Control = VFCOMP_STORE_SRC,
-         .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);
-
-      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_INSTANCING,
-                     .InstancingEnable = instancing_enable[desc->binding],
-                     .VertexElementIndex = i,
-                     /* Vulkan so far doesn't have an instance divisor, so
-                      * this is always 1 (ignored if not instancing). */
-                     .InstanceDataStepRate = 1);
-   }
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_SGVS,
-                  .VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
-                  .VertexIDComponentNumber = 2,
-                  .VertexIDElementOffset = info->bindingCount,
-                  .InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
-                  .InstanceIDComponentNumber = 3,
-                  .InstanceIDElementOffset = info->bindingCount);
-}
-
-static void
-emit_ia_state(struct anv_pipeline *pipeline,
-              const VkPipelineInputAssemblyStateCreateInfo *info,
-              const struct anv_graphics_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_LINESTRIP_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
-   };
-   uint32_t topology = vk_to_gen_primitive_type[info->topology];
-
-   if (extra && extra->use_rectlist)
-      topology = _3DPRIM_RECTLIST;
-
-   struct GEN8_3DSTATE_VF vf = {
-      GEN8_3DSTATE_VF_header,
-      .IndexedDrawCutIndexEnable = info->primitiveRestartEnable,
-   };
-   GEN8_3DSTATE_VF_pack(NULL, pipeline->state_vf, &vf);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
-                  .PrimitiveTopologyType = topology);
-}
-
-static void
-emit_rs_state(struct anv_pipeline *pipeline,
-              const VkPipelineRasterStateCreateInfo *info,
-              const struct anv_graphics_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
-   };
-
-   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
-   };
-
-   static const uint32_t vk_to_gen_front_face[] = {
-      [VK_FRONT_FACE_CCW]                       = CounterClockwise,
-      [VK_FRONT_FACE_CW]                        = Clockwise
-   };
-
-   struct GEN8_3DSTATE_SF sf = {
-      GEN8_3DSTATE_SF_header,
-      .ViewportTransformEnable = !(extra && extra->disable_viewport),
-      .TriangleStripListProvokingVertexSelect = 0,
-      .LineStripListProvokingVertexSelect = 0,
-      .TriangleFanProvokingVertexSelect = 0,
-      .PointWidthSource = pipeline->writes_point_size ? Vertex : State,
-      .PointWidth = 1.0,
-   };
-
-   /* FINISHME: VkBool32 rasterizerDiscardEnable; */
-
-   GEN8_3DSTATE_SF_pack(NULL, pipeline->state_sf, &sf);
-
-   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,
-                  .ForceVertexURBEntryReadOffset = false,
-                  .PointSpriteTextureCoordinateOrigin = UPPERLEFT,
-                  .NumberofSFOutputAttributes =
-                     pipeline->wm_prog_data.num_varying_inputs);
-
-}
-
-static void
-emit_cb_state(struct anv_pipeline *pipeline,
-              const VkPipelineColorBlendStateCreateInfo *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 = GEN8_BLEND_STATE_length;
-   pipeline->blend_state =
-      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
-
-   struct GEN8_BLEND_STATE blend_state = {
-      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
-   };
-
-   for (uint32_t i = 0; i < info->attachmentCount; i++) {
-      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[i];
-
-      blend_state.Entry[i] = (struct GEN8_BLEND_STATE_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_pack(NULL, pipeline->blend_state.map, &blend_state);
-
-   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,
-              const VkPipelineDepthStencilStateCreateInfo *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;
-   }
-
-   /* VkBool32 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
-gen8_graphics_pipeline_create(
-    VkDevice                                    _device,
-    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
-    const struct anv_graphics_pipeline_create_info *extra,
-    VkPipeline*                                 pPipeline)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_pipeline *pipeline;
-   VkResult result;
-   uint32_t offset, length;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_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->device = device;
-   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
-   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
-
-   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);
-   pipeline->batch.relocs = &pipeline->batch_relocs;
-
-   anv_state_stream_init(&pipeline->program_stream,
-                         &device->instruction_block_pool);
-
-   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
-      pipeline->shaders[pCreateInfo->pStages[i].stage] =
-         anv_shader_from_handle(pCreateInfo->pStages[i].shader);
-   }
-
-   if (pCreateInfo->pTessellationState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
-   if (pCreateInfo->pViewportState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
-   if (pCreateInfo->pMultisampleState)
-      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
-
-   pipeline->use_repclear = extra && extra->use_repclear;
-
-   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 =
-         pCreateInfo->pVertexInputState->attributeCount - 2;
-   }
-
-   assert(pCreateInfo->pVertexInputState);
-   emit_vertex_input(pipeline, pCreateInfo->pVertexInputState);
-   assert(pCreateInfo->pInputAssemblyState);
-   emit_ia_state(pipeline, pCreateInfo->pInputAssemblyState, extra);
-   assert(pCreateInfo->pRasterState);
-   emit_rs_state(pipeline, pCreateInfo->pRasterState, extra);
-   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
-   emit_cb_state(pipeline, pCreateInfo->pColorBlendState);
-
-   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),
-                  .MinimumPointWidth = 0.125,
-                  .MaximumPointWidth = 255.875);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM,
-                  .StatisticsEnable = true,
-                  .LineEndCapAntialiasingRegionWidth = _05pixels,
-                  .LineAntialiasingRegionWidth = _10pixels,
-                  .EarlyDepthStencilControl = NORMAL,
-                  .ForceThreadDispatchEnable = NORMAL,
-                  .PointRasterizationRule = RASTRULE_UPPER_RIGHT,
-                  .BarycentricInterpolationMode =
-                     pipeline->wm_prog_data.barycentric_interp_modes);
-
-   uint32_t samples = 1;
-   uint32_t log2_samples = __builtin_ffs(samples) - 1;
-   bool enable_sampling = samples > 1 ? true : false;
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_MULTISAMPLE,
-                  .PixelPositionOffsetEnable = enable_sampling,
-                  .PixelLocation = CENTER,
-                  .NumberofMultisamples = log2_samples);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SAMPLE_MASK,
-                  .SampleMask = 0xffff);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_VS,
-                  .VSURBStartingAddress = pipeline->urb.vs_start,
-                  .VSURBEntryAllocationSize = pipeline->urb.vs_size - 1,
-                  .VSNumberofURBEntries = pipeline->urb.nr_vs_entries);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_GS,
-                  .GSURBStartingAddress = pipeline->urb.gs_start,
-                  .GSURBEntryAllocationSize = pipeline->urb.gs_size - 1,
-                  .GSNumberofURBEntries = pipeline->urb.nr_gs_entries);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_HS,
-                  .HSURBStartingAddress = pipeline->urb.vs_start,
-                  .HSURBEntryAllocationSize = 0,
-                  .HSNumberofURBEntries = 0);
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_DS,
-                  .DSURBStartingAddress = pipeline->urb.vs_start,
-                  .DSURBEntryAllocationSize = 0,
-                  .DSNumberofURBEntries = 0);
-
-   const struct brw_gs_prog_data *gs_prog_data = &pipeline->gs_prog_data;
-   offset = 1;
-   length = (gs_prog_data->base.vue_map.num_slots + 1) / 2 - offset;
-
-   if (pipeline->gs_vec4 == NO_KERNEL)
-      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS, .Enable = false);
-   else
-      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS,
-                     .SingleProgramFlow = false,
-                     .KernelStartPointer = pipeline->gs_vec4,
-                     .VectorMaskEnable = Vmask,
-                     .SamplerCount = 0,
-                     .BindingTableEntryCount = 0,
-                     .ExpectedVertexCount = pipeline->gs_vertex_count,
-
-                     .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,
-                     .VertexURBEntryReadLength = gs_prog_data->base.urb_read_length,
-                     .DispatchGRFStartRegisterForURBData =
-                        gs_prog_data->base.base.dispatch_grf_start_reg,
-
-                     .MaximumNumberofThreads = device->info.max_gs_threads,
-                     .ControlDataHeaderSize = gs_prog_data->control_data_header_size_hwords,
-                     //pipeline->gs_prog_data.dispatch_mode |
-                     .StatisticsEnable = true,
-                     .IncludePrimitiveID = gs_prog_data->include_primitive_id,
-                     .ReorderMode = TRAILING,
-                     .Enable = true,
-
-                     .ControlDataFormat = gs_prog_data->control_data_format,
-
-                     /* FIXME: mesa sets this based on ctx->Transform.ClipPlanesEnabled:
-                      * UserClipDistanceClipTestEnableBitmask_3DSTATE_GS(v)
-                      * UserClipDistanceCullTestEnableBitmask(v)
-                      */
-
-                     .VertexURBEntryOutputReadOffset = offset,
-                     .VertexURBEntryOutputLength = length);
-
-   const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
-   /* Skip the VUE header and position slots */
-   offset = 1;
-   length = (vue_prog_data->vue_map.num_slots + 1) / 2 - offset;
-
-   if (pipeline->vs_simd8 == NO_KERNEL || (extra && extra->disable_vs))
-      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(pCreateInfo->pVertexInputState->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,
-
-                     .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,
-                     .VertexURBEntryReadLength = vue_prog_data->urb_read_length,
-                     .VertexURBEntryReadOffset = 0,
-
-                     .MaximumNumberofThreads = device->info.max_vs_threads - 1,
-                     .StatisticsEnable = false,
-                     .SIMD8DispatchEnable = true,
-                     .VertexCacheDisable = false,
-                     .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;
-
-   ksp2 = 0;
-   grf_start2 = 0;
-   if (pipeline->ps_simd8 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd8;
-      grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
-      if (pipeline->ps_simd16 != NO_KERNEL) {
-         ksp2 = pipeline->ps_simd16;
-         grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
-      }
-   } else if (pipeline->ps_simd16 != NO_KERNEL) {
-      ksp0 = pipeline->ps_simd16;
-      grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
-   } else {
-      unreachable("no ps shader");
-   }
-
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
-                  .KernelStartPointer0 = ksp0,
-
-                  .SingleProgramFlow = false,
-                  .VectorMaskEnable = true,
-                  .SamplerCount = 1,
-
-                  .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 ?
-                     POSOFFSET_SAMPLE: POSOFFSET_NONE,
-                  .PushConstantEnable = wm_prog_data->base.nr_params > 0,
-                  ._8PixelDispatchEnable = pipeline->ps_simd8 != NO_KERNEL,
-                  ._16PixelDispatchEnable = pipeline->ps_simd16 != NO_KERNEL,
-                  ._32PixelDispatchEnable = false,
-
-                  .DispatchGRFStartRegisterForConstantSetupData0 = grf_start0,
-                  .DispatchGRFStartRegisterForConstantSetupData1 = 0,
-                  .DispatchGRFStartRegisterForConstantSetupData2 = grf_start2,
-
-                  .KernelStartPointer1 = 0,
-                  .KernelStartPointer2 = ksp2);
-
-   bool per_sample_ps = false;
-   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS_EXTRA,
-                  .PixelShaderValid = true,
-                  .PixelShaderKillsPixel = wm_prog_data->uses_kill,
-                  .PixelShaderComputedDepthMode = wm_prog_data->computed_depth_mode,
-                  .AttributeEnable = wm_prog_data->num_varying_inputs > 0,
-                  .oMaskPresenttoRenderTarget = wm_prog_data->uses_omask,
-                  .PixelShaderIsPerSample = per_sample_ps);
-
-   *pPipeline = anv_pipeline_to_handle(pipeline);
-
-   return VK_SUCCESS;
-}
-
-VkResult gen8_compute_pipeline_create(
-    VkDevice                                    _device,
-    const VkComputePipelineCreateInfo*          pCreateInfo,
-    VkPipeline*                                 pPipeline)
-{
-   ANV_FROM_HANDLE(anv_device, 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->device = device;
-   pipeline->layout = anv_pipeline_layout_from_handle(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);
-   pipeline->batch.relocs = &pipeline->batch_relocs;
-
-   anv_state_stream_init(&pipeline->program_stream,
-                         &device->instruction_block_pool);
-
-   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
-
-   pipeline->shaders[VK_SHADER_STAGE_COMPUTE] =
-      anv_shader_from_handle(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 = anv_pipeline_to_handle(pipeline);
-
-   return VK_SUCCESS;
-}
-
-VkResult gen8_CreateDynamicDepthStencilState(
-    VkDevice                                    _device,
-    const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
-    VkDynamicDepthStencilState*                 pState)
-{
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   struct anv_dynamic_ds_state *state;
-
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
-
-   state = anv_device_alloc(device, sizeof(*state), 8,
-                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (state == NULL)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
-      GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
-
-      /* Is this what we need to do? */
-      .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
-
-      .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
-      .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
-
-      .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
-      .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
-   };
-
-   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
-                                      &wm_depth_stencil);
-
-   struct GEN8_COLOR_CALC_STATE color_calc_state = {
-      .StencilReferenceValue = pCreateInfo->stencilFrontRef,
-      .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
-   };
-
-   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
-
-   *pState = anv_dynamic_ds_state_to_handle(state);
-
-   return VK_SUCCESS;
-}
-
-static void
-emit_ps_depth_count(struct anv_batch *batch,
-                    struct anv_bo *bo, uint32_t offset)
-{
-   anv_batch_emit(batch, GEN8_PIPE_CONTROL,
-                  .DestinationAddressType = DAT_PPGTT,
-                  .PostSyncOperation = WritePSDepthCount,
-                  .Address = { bo, offset });  /* FIXME: This is only lower 32 bits */
-}
-
-void gen8_CmdBeginQuery(
-    VkCmdBuffer                                 cmdBuffer,
-    VkQueryPool                                 queryPool,
-    uint32_t                                    slot,
-    VkQueryControlFlags                         flags)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
-
-   switch (pool->type) {
-   case VK_QUERY_TYPE_OCCLUSION:
-      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
-                                    slot * sizeof(struct anv_query_pool_slot));
-      break;
-
-   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
-   default:
-      unreachable("");
-   }
-}
-
-void gen8_CmdEndQuery(
-    VkCmdBuffer                                 cmdBuffer,
-    VkQueryPool                                 queryPool,
-    uint32_t                                    slot)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
-
-   switch (pool->type) {
-   case VK_QUERY_TYPE_OCCLUSION:
-      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
-                          slot * sizeof(struct anv_query_pool_slot) + 8);
-      break;
-
-   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
-   default:
-      unreachable("");
-   }
-}
-
-#define TIMESTAMP 0x2358
-
-void gen8_CmdWriteTimestamp(
-    VkCmdBuffer                                 cmdBuffer,
-    VkTimestampType                             timestampType,
-    VkBuffer                                    destBuffer,
-    VkDeviceSize                                destOffset)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
-   struct anv_bo *bo = buffer->bo;
-
-   switch (timestampType) {
-   case VK_TIMESTAMP_TYPE_TOP:
-      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
-                     .RegisterAddress = TIMESTAMP,
-                     .MemoryAddress = { bo, buffer->offset + destOffset });
-      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
-                     .RegisterAddress = TIMESTAMP + 4,
-                     .MemoryAddress = { bo, buffer->offset + destOffset + 4 });
-      break;
-
-   case VK_TIMESTAMP_TYPE_BOTTOM:
-      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
-                     .DestinationAddressType = DAT_PPGTT,
-                     .PostSyncOperation = WriteTimestamp,
-                     .Address = /* FIXME: This is only lower 32 bits */
-                        { bo, buffer->offset + destOffset });
-      break;
-
-   default:
-      break;
-   }
-}
-
-#define alu_opcode(v)   __gen_field((v),  20, 31)
-#define alu_operand1(v) __gen_field((v),  10, 19)
-#define alu_operand2(v) __gen_field((v),   0,  9)
-#define alu(opcode, operand1, operand2) \
-   alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
-
-#define OPCODE_NOOP      0x000
-#define OPCODE_LOAD      0x080
-#define OPCODE_LOADINV   0x480
-#define OPCODE_LOAD0     0x081
-#define OPCODE_LOAD1     0x481
-#define OPCODE_ADD       0x100
-#define OPCODE_SUB       0x101
-#define OPCODE_AND       0x102
-#define OPCODE_OR        0x103
-#define OPCODE_XOR       0x104
-#define OPCODE_STORE     0x180
-#define OPCODE_STOREINV  0x580
-
-#define OPERAND_R0   0x00
-#define OPERAND_R1   0x01
-#define OPERAND_R2   0x02
-#define OPERAND_R3   0x03
-#define OPERAND_R4   0x04
-#define OPERAND_SRCA 0x20
-#define OPERAND_SRCB 0x21
-#define OPERAND_ACCU 0x31
-#define OPERAND_ZF   0x32
-#define OPERAND_CF   0x33
-
-#define CS_GPR(n) (0x2600 + (n) * 8)
-
-static void
-emit_load_alu_reg_u64(struct anv_batch *batch, uint32_t reg,
-                      struct anv_bo *bo, uint32_t offset)
-{
-   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
-                  .RegisterAddress = reg,
-                  .MemoryAddress = { bo, offset });
-   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
-                  .RegisterAddress = reg + 4,
-                  .MemoryAddress = { bo, offset + 4 });
-}
-
-void gen8_CmdCopyQueryPoolResults(
-    VkCmdBuffer                                 cmdBuffer,
-    VkQueryPool                                 queryPool,
-    uint32_t                                    startQuery,
-    uint32_t                                    queryCount,
-    VkBuffer                                    destBuffer,
-    VkDeviceSize                                destOffset,
-    VkDeviceSize                                destStride,
-    VkQueryResultFlags                          flags)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
-   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
-   uint32_t slot_offset, dst_offset;
-
-   if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
-      /* Where is the availabilty info supposed to go? */
-      anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
-      return;
-   }
-
-   assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
-
-   /* FIXME: If we're not waiting, should we just do this on the CPU? */
-   if (flags & VK_QUERY_RESULT_WAIT_BIT)
-      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
-                     .CommandStreamerStallEnable = true,
-                     .StallAtPixelScoreboard = true);
-
-   dst_offset = buffer->offset + destOffset;
-   for (uint32_t i = 0; i < queryCount; i++) {
-
-      slot_offset = (startQuery + i) * sizeof(struct anv_query_pool_slot);
-
-      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(0), &pool->bo, slot_offset);
-      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(1), &pool->bo, slot_offset + 8);
-
-      /* FIXME: We need to clamp the result for 32 bit. */
-
-      uint32_t *dw = anv_batch_emitn(&cmd_buffer->batch, 5, GEN8_MI_MATH);
-      dw[1] = alu(OPCODE_LOAD, OPERAND_SRCA, OPERAND_R1);
-      dw[2] = alu(OPCODE_LOAD, OPERAND_SRCB, OPERAND_R0);
-      dw[3] = alu(OPCODE_SUB, 0, 0);
-      dw[4] = alu(OPCODE_STORE, OPERAND_R2, OPERAND_ACCU);
-
-      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
-                     .RegisterAddress = CS_GPR(2),
-                     /* FIXME: This is only lower 32 bits */
-                     .MemoryAddress = { buffer->bo, dst_offset });
-
-      if (flags & VK_QUERY_RESULT_64_BIT)
-         anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
-                        .RegisterAddress = CS_GPR(2) + 4,
-                        /* FIXME: This is only lower 32 bits */
-                        .MemoryAddress = { buffer->bo, dst_offset + 4 });
-
-      dst_offset += destStride;
-   }
-}
-
-void
-gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
-{
-   struct anv_device *device = cmd_buffer->device;
-   struct anv_bo *scratch_bo = NULL;
-
-   cmd_buffer->state.scratch_size =
-      anv_block_pool_size(&device->scratch_block_pool);
-   if (cmd_buffer->state.scratch_size > 0)
-      scratch_bo = &device->scratch_block_pool.bo;
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
-                  .GeneralStateBaseAddress = { scratch_bo, 0 },
-                  .GeneralStateMemoryObjectControlState = GEN8_MOCS,
-                  .GeneralStateBaseAddressModifyEnable = true,
-                  .GeneralStateBufferSize = 0xfffff,
-                  .GeneralStateBufferSizeModifyEnable = true,
-
-                  .SurfaceStateBaseAddress = { anv_cmd_buffer_current_surface_bo(cmd_buffer), 0 },
-                  .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
-                  .SurfaceStateBaseAddressModifyEnable = true,
-
-                  .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
-                  .DynamicStateMemoryObjectControlState = GEN8_MOCS,
-                  .DynamicStateBaseAddressModifyEnable = true,
-                  .DynamicStateBufferSize = 0xfffff,
-                  .DynamicStateBufferSizeModifyEnable = true,
-
-                  .IndirectObjectBaseAddress = { NULL, 0 },
-                  .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
-                  .IndirectObjectBaseAddressModifyEnable = true,
-                  .IndirectObjectBufferSize = 0xfffff,
-                  .IndirectObjectBufferSizeModifyEnable = true,
-
-                  .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
-                  .InstructionMemoryObjectControlState = GEN8_MOCS,
-                  .InstructionBaseAddressModifyEnable = true,
-                  .InstructionBufferSize = 0xfffff,
-                  .InstructionBuffersizeModifyEnable = true);
-
-   /* After re-setting the surface state base address, we have to do some
-    * cache flusing so that the sampler engine will pick up the new
-    * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
-    * Shared Function > 3D Sampler > State > State Caching (page 96):
-    *
-    *    Coherency with system memory in the state cache, like the texture
-    *    cache is handled partially by software. It is expected that the
-    *    command stream or shader will issue Cache Flush operation or
-    *    Cache_Flush sampler message to ensure that the L1 cache remains
-    *    coherent with system memory.
-    *
-    *    [...]
-    *
-    *    Whenever the value of the Dynamic_State_Base_Addr,
-    *    Surface_State_Base_Addr are altered, the L1 state cache must be
-    *    invalidated to ensure the new surface or sampler state is fetched
-    *    from system memory.
-    *
-    * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
-    * which, according the PIPE_CONTROL instruction documentation in the
-    * Broadwell PRM:
-    *
-    *    Setting this bit is independent of any other bit in this packet.
-    *    This bit controls the invalidation of the L1 and L2 state caches
-    *    at the top of the pipe i.e. at the parsing time.
-    *
-    * Unfortunately, experimentation seems to indicate that state cache
-    * invalidation through a PIPE_CONTROL does nothing whatsoever in
-    * regards to surface state and binding tables.  In stead, it seems that
-    * invalidating the texture cache is what is actually needed.
-    *
-    * XXX:  As far as we have been able to determine through
-    * experimentation, shows that flush the texture cache appears to be
-    * sufficient.  The theory here is that all of the sampling/rendering
-    * units cache the binding table in the texture cache.  However, we have
-    * yet to be able to actually confirm this.
-    */
-   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
-                  .TextureCacheInvalidationEnable = true);
-}
-
-void gen8_CmdBindIndexBuffer(
-    VkCmdBuffer                                 cmdBuffer,
-    VkBuffer                                    _buffer,
-    VkDeviceSize                                offset,
-    VkIndexType                                 indexType)
-{
-   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
-   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
-
-   static const uint32_t vk_to_gen_index_type[] = {
-      [VK_INDEX_TYPE_UINT16]                    = INDEX_WORD,
-      [VK_INDEX_TYPE_UINT32]                    = INDEX_DWORD,
-   };
-
-   struct GEN8_3DSTATE_VF vf = {
-      GEN8_3DSTATE_VF_header,
-      .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
-   };
-   GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state.state_vf, &vf);
-
-   cmd_buffer->state.dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
-
-   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
-                  .IndexFormat = vk_to_gen_index_type[indexType],
-                  .MemoryObjectControlState = GEN8_MOCS,
-                  .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
-                  .BufferSize = buffer->size - offset);
-}
index 38906a916dabedbc720d605fb734e440543105b8..8f681230292f678014b60137e438feb16932517f 100644 (file)
@@ -279,7 +279,7 @@ meta_emit_clear(struct anv_cmd_buffer *cmd_buffer,
       anv_CmdBindDynamicColorBlendState(anv_cmd_buffer_to_handle(cmd_buffer),
                                         device->meta_state.shared.cb_state);
 
-   anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, num_instances);
+   driver_layer->CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, num_instances);
 }
 
 void
@@ -694,7 +694,7 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
          .dependencyCount = 0,
       }, &pass);
 
-   anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
+   driver_layer->CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
       &(VkRenderPassBeginInfo) {
          .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
          .renderPass = pass,
@@ -715,9 +715,9 @@ meta_emit_blit(struct anv_cmd_buffer *cmd_buffer,
                              device->meta_state.blit.pipeline_layout, 0, 1,
                              &set, 0, NULL);
 
-   anv_CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
+   driver_layer->CmdDraw(anv_cmd_buffer_to_handle(cmd_buffer), 0, 3, 0, 1);
 
-   anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
+   driver_layer->CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
 
    /* At the point where we emit the draw call, all data from the
     * descriptor sets, etc. has been used.  We are free to delete it.
@@ -1345,7 +1345,7 @@ void anv_CmdClearColorImage(
                   .dependencyCount = 0,
                }, &pass);
 
-            anv_CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
+            driver_layer->CmdBeginRenderPass(anv_cmd_buffer_to_handle(cmd_buffer),
                &(VkRenderPassBeginInfo) {
                   .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
                   .renderArea = {
@@ -1373,7 +1373,7 @@ void anv_CmdClearColorImage(
             meta_emit_clear(cmd_buffer, 1, &instance_data,
                             (VkClearDepthStencilValue) {0});
 
-            anv_CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
+            driver_layer->CmdEndRenderPass(anv_cmd_buffer_to_handle(cmd_buffer));
          }
       }
    }
index 0b422d257a9fe98e1357b1378816a00c6c165a93..3a46e37bc3a0605ab36398567a9585c1091e32a0 100644 (file)
@@ -761,6 +761,21 @@ void anv_cmd_buffer_add_secondary(struct anv_cmd_buffer *primary,
                                   struct anv_cmd_buffer *secondary);
 void anv_cmd_buffer_prepare_execbuf(struct anv_cmd_buffer *cmd_buffer);
 
+VkResult anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
+                                           unsigned stage, struct anv_state *bt_state);
+VkResult anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
+                                      unsigned stage, struct anv_state *state);
+void anv_flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer);
+
+struct anv_state anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                                             uint32_t *a, uint32_t dwords,
+                                             uint32_t alignment);
+struct anv_state anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
+                                              uint32_t *a, uint32_t *b,
+                                              uint32_t dwords, uint32_t alignment);
+void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                  struct anv_subpass *subpass);
+
 struct anv_bo *
 anv_cmd_buffer_current_surface_bo(struct anv_cmd_buffer *cmd_buffer);
 struct anv_reloc_list *
@@ -774,9 +789,12 @@ anv_cmd_buffer_alloc_dynamic_state(struct anv_cmd_buffer *cmd_buffer,
 
 VkResult anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer *cmd_buffer);
 
+void gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+
 void anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
 
-void gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer);
+void gen8_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                                   struct anv_subpass *subpass);
 
 void anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
                                   struct anv_subpass *subpass);
diff --git a/src/vulkan/gen8_cmd_buffer.c b/src/vulkan/gen8_cmd_buffer.c
new file mode 100644 (file)
index 0000000..59a2108
--- /dev/null
@@ -0,0 +1,814 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+gen8_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
+   uint32_t *p;
+
+   uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
+
+   assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
+
+   if (cmd_buffer->state.current_pipeline != _3D) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
+                     .PipelineSelection = _3D);
+      cmd_buffer->state.current_pipeline = _3D;
+   }
+
+   if (vb_emit) {
+      const uint32_t num_buffers = __builtin_popcount(vb_emit);
+      const uint32_t num_dwords = 1 + num_buffers * 4;
+
+      p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
+                          GEN8_3DSTATE_VERTEX_BUFFERS);
+      uint32_t vb, i = 0;
+      for_each_bit(vb, vb_emit) {
+         struct anv_buffer *buffer = cmd_buffer->state.vertex_bindings[vb].buffer;
+         uint32_t offset = cmd_buffer->state.vertex_bindings[vb].offset;
+
+         struct GEN8_VERTEX_BUFFER_STATE state = {
+            .VertexBufferIndex = vb,
+            .MemoryObjectControlState = GEN8_MOCS,
+            .AddressModifyEnable = true,
+            .BufferPitch = pipeline->binding_stride[vb],
+            .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+            .BufferSize = buffer->size - offset
+         };
+
+         GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
+         i++;
+      }
+   }
+
+   if (cmd_buffer->state.dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY) {
+      /* If somebody compiled a pipeline after starting a command buffer the
+       * scratch bo may have grown since we started this cmd buffer (and
+       * emitted STATE_BASE_ADDRESS).  If we're binding that pipeline now,
+       * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
+      if (cmd_buffer->state.scratch_size < pipeline->total_scratch)
+         anv_cmd_buffer_emit_state_base_address(cmd_buffer);
+
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+   }
+
+   if (cmd_buffer->state.descriptors_dirty)
+      anv_flush_descriptor_sets(cmd_buffer);
+
+   if (cmd_buffer->state.dirty & ANV_CMD_BUFFER_VP_DIRTY) {
+      struct anv_dynamic_vp_state *vp_state = cmd_buffer->state.vp_state;
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
+                     .ScissorRectPointer = vp_state->scissor.offset);
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
+                     .CCViewportPointer = vp_state->cc_vp.offset);
+      anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
+                     .SFClipViewportPointer = vp_state->sf_clip_vp.offset);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
+                                  ANV_CMD_BUFFER_RS_DIRTY)) {
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->state.rs_state->state_sf,
+                           pipeline->state_sf);
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->state.rs_state->state_raster,
+                           pipeline->state_raster);
+   }
+
+   if (cmd_buffer->state.ds_state &&
+       (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
+                                   ANV_CMD_BUFFER_DS_DIRTY))) {
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->state.ds_state->state_wm_depth_stencil,
+                           pipeline->state_wm_depth_stencil);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_CB_DIRTY |
+                                  ANV_CMD_BUFFER_DS_DIRTY)) {
+      struct anv_state state;
+      if (cmd_buffer->state.ds_state == NULL)
+         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
+                                             cmd_buffer->state.cb_state->state_color_calc,
+                                             GEN8_COLOR_CALC_STATE_length, 64);
+      else if (cmd_buffer->state.cb_state == NULL)
+         state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
+                                             cmd_buffer->state.ds_state->state_color_calc,
+                                             GEN8_COLOR_CALC_STATE_length, 64);
+      else
+         state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
+                                              cmd_buffer->state.ds_state->state_color_calc,
+                                              cmd_buffer->state.cb_state->state_color_calc,
+                                              GEN8_COLOR_CALC_STATE_length, 64);
+
+      anv_batch_emit(&cmd_buffer->batch,
+                     GEN8_3DSTATE_CC_STATE_POINTERS,
+                     .ColorCalcStatePointer = state.offset,
+                     .ColorCalcStatePointerValid = true);
+   }
+
+   if (cmd_buffer->state.dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY |
+                                  ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY)) {
+      anv_batch_emit_merge(&cmd_buffer->batch,
+                           cmd_buffer->state.state_vf, pipeline->state_vf);
+   }
+
+   cmd_buffer->state.vb_dirty &= ~vb_emit;
+   cmd_buffer->state.dirty = 0;
+}
+
+void gen8_CmdDraw(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    firstVertex,
+    uint32_t                                    vertexCount,
+    uint32_t                                    firstInstance,
+    uint32_t                                    instanceCount)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .VertexAccessType = SEQUENTIAL,
+                  .VertexCountPerInstance = vertexCount,
+                  .StartVertexLocation = firstVertex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = 0);
+}
+
+void gen8_CmdDrawIndexed(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    firstIndex,
+    uint32_t                                    indexCount,
+    int32_t                                     vertexOffset,
+    uint32_t                                    firstInstance,
+    uint32_t                                    instanceCount)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .VertexAccessType = RANDOM,
+                  .VertexCountPerInstance = indexCount,
+                  .StartVertexLocation = firstIndex,
+                  .InstanceCount = instanceCount,
+                  .StartInstanceLocation = firstInstance,
+                  .BaseVertexLocation = vertexOffset);
+}
+
+static void
+emit_lrm(struct anv_batch *batch,
+         uint32_t reg, struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+}
+
+static void
+emit_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
+                  .RegisterOffset = reg,
+                  .DataDWord = imm);
+}
+
+/* Auto-Draw / Indirect Registers */
+#define GEN7_3DPRIM_END_OFFSET          0x2420
+#define GEN7_3DPRIM_START_VERTEX        0x2430
+#define GEN7_3DPRIM_VERTEX_COUNT        0x2434
+#define GEN7_3DPRIM_INSTANCE_COUNT      0x2438
+#define GEN7_3DPRIM_START_INSTANCE      0x243C
+#define GEN7_3DPRIM_BASE_VERTEX         0x2440
+
+void gen8_CmdDrawIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
+   emit_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = SEQUENTIAL);
+}
+
+void gen8_CmdBindIndexBuffer(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    VkIndexType                                 indexType)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+
+   static const uint32_t vk_to_gen_index_type[] = {
+      [VK_INDEX_TYPE_UINT16]                    = INDEX_WORD,
+      [VK_INDEX_TYPE_UINT32]                    = INDEX_DWORD,
+   };
+
+   struct GEN8_3DSTATE_VF vf = {
+      GEN8_3DSTATE_VF_header,
+      .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
+   };
+   GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state.state_vf, &vf);
+
+   cmd_buffer->state.dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
+                  .IndexFormat = vk_to_gen_index_type[indexType],
+                  .MemoryObjectControlState = GEN8_MOCS,
+                  .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
+                  .BufferSize = buffer->size - offset);
+}
+
+static VkResult
+gen8_flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct anv_state surfaces = { 0, }, samplers = { 0, };
+   VkResult result;
+
+   result = anv_cmd_buffer_emit_samplers(cmd_buffer,
+                                         VK_SHADER_STAGE_COMPUTE, &samplers);
+   if (result != VK_SUCCESS)
+      return result;
+   result = anv_cmd_buffer_emit_binding_table(cmd_buffer,
+                                               VK_SHADER_STAGE_COMPUTE, &surfaces);
+   if (result != VK_SUCCESS)
+      return result;
+
+   struct GEN8_INTERFACE_DESCRIPTOR_DATA desc = {
+      .KernelStartPointer = pipeline->cs_simd,
+      .KernelStartPointerHigh = 0,
+      .BindingTablePointer = surfaces.offset,
+      .BindingTableEntryCount = 0,
+      .SamplerStatePointer = samplers.offset,
+      .SamplerCount = 0,
+      .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
+   };
+
+   uint32_t size = GEN8_INTERFACE_DESCRIPTOR_DATA_length * sizeof(uint32_t);
+   struct anv_state state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, size, 64);
+
+   GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
+                  .InterfaceDescriptorTotalLength = size,
+                  .InterfaceDescriptorDataStartAddress = state.offset);
+
+   return VK_SUCCESS;
+}
+
+static void
+gen8_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   VkResult result;
+
+   assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
+
+   if (cmd_buffer->state.current_pipeline != GPGPU) {
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
+                     .PipelineSelection = GPGPU);
+      cmd_buffer->state.current_pipeline = GPGPU;
+   }
+
+   if (cmd_buffer->state.compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
+      anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
+
+   if ((cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_COMPUTE_BIT) ||
+       (cmd_buffer->state.compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)) {
+      result = gen8_flush_compute_descriptor_set(cmd_buffer);
+      assert(result == VK_SUCCESS);
+      cmd_buffer->state.descriptors_dirty &= ~VK_SHADER_STAGE_COMPUTE;
+   }
+
+   cmd_buffer->state.compute_dirty = 0;
+}
+
+void gen8_CmdDrawIndexedIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    count,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
+   emit_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
+                  .IndirectParameterEnable = true,
+                  .VertexAccessType = RANDOM);
+}
+
+void gen8_CmdDispatch(
+    VkCmdBuffer                                 cmdBuffer,
+    uint32_t                                    x,
+    uint32_t                                    y,
+    uint32_t                                    z)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+
+   gen8_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .ThreadGroupIDXDimension = x,
+                  .ThreadGroupIDYDimension = y,
+                  .ThreadGroupIDZDimension = z,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
+}
+
+#define GPGPU_DISPATCHDIMX 0x2500
+#define GPGPU_DISPATCHDIMY 0x2504
+#define GPGPU_DISPATCHDIMZ 0x2508
+
+void gen8_CmdDispatchIndirect(
+    VkCmdBuffer                                 cmdBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
+   struct brw_cs_prog_data *prog_data = &pipeline->cs_prog_data;
+   struct anv_bo *bo = buffer->bo;
+   uint32_t bo_offset = buffer->offset + offset;
+
+   gen8_cmd_buffer_flush_compute_state(cmd_buffer);
+
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMX, bo, bo_offset);
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMY, bo, bo_offset + 4);
+   emit_lrm(&cmd_buffer->batch, GPGPU_DISPATCHDIMZ, bo, bo_offset + 8);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_GPGPU_WALKER,
+                  .IndirectParameterEnable = true,
+                  .SIMDSize = prog_data->simd_size / 16,
+                  .ThreadDepthCounterMaximum = 0,
+                  .ThreadHeightCounterMaximum = 0,
+                  .ThreadWidthCounterMaximum = pipeline->cs_thread_width_max,
+                  .RightExecutionMask = pipeline->cs_right_mask,
+                  .BottomExecutionMask = 0xffffffff);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
+}
+
+static void
+gen8_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_subpass *subpass = cmd_buffer->state.subpass;
+   struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
+   const struct anv_depth_stencil_view *view;
+
+   static const struct anv_depth_stencil_view null_view =
+      { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
+
+   if (subpass->depth_stencil_attachment != VK_ATTACHMENT_UNUSED) {
+      const struct anv_attachment_view *aview =
+         fb->attachments[subpass->depth_stencil_attachment];
+      assert(aview->attachment_type == ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL);
+      view = (const struct anv_depth_stencil_view *)aview;
+   } else {
+      view = &null_view;
+   }
+
+   /* FIXME: Implement the PMA stall W/A */
+   /* FIXME: Width and Height are wrong */
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
+                  .SurfaceType = SURFTYPE_2D,
+                  .DepthWriteEnable = view->depth_stride > 0,
+                  .StencilWriteEnable = view->stencil_stride > 0,
+                  .HierarchicalDepthBufferEnable = false,
+                  .SurfaceFormat = view->depth_format,
+                  .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
+                  .SurfaceBaseAddress = { view->bo,  view->depth_offset },
+                  .Height = cmd_buffer->state.framebuffer->height - 1,
+                  .Width = cmd_buffer->state.framebuffer->width - 1,
+                  .LOD = 0,
+                  .Depth = 1 - 1,
+                  .MinimumArrayElement = 0,
+                  .DepthBufferObjectControlState = GEN8_MOCS,
+                  .RenderTargetViewExtent = 1 - 1,
+                  .SurfaceQPitch = view->depth_qpitch >> 2);
+
+   /* Disable hierarchial depth buffers. */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
+                  .StencilBufferEnable = view->stencil_stride > 0,
+                  .StencilBufferObjectControlState = GEN8_MOCS,
+                  .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
+                  .SurfaceBaseAddress = { view->bo, view->stencil_offset },
+                  .SurfaceQPitch = view->stencil_qpitch >> 2);
+
+   /* Clear the clear params. */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
+}
+
+void
+gen8_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
+                             struct anv_subpass *subpass)
+{
+   cmd_buffer->state.subpass = subpass;
+
+   cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
+
+   gen8_cmd_buffer_emit_depth_stencil(cmd_buffer);
+}
+
+void gen8_CmdBeginRenderPass(
+    VkCmdBuffer                                 cmdBuffer,
+    const VkRenderPassBeginInfo*                pRenderPassBegin,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_render_pass, pass, pRenderPassBegin->renderPass);
+   ANV_FROM_HANDLE(anv_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
+
+   cmd_buffer->state.framebuffer = framebuffer;
+   cmd_buffer->state.pass = pass;
+
+   const VkRect2D *render_area = &pRenderPassBegin->renderArea;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
+                  .ClippedDrawingRectangleYMin = render_area->offset.y,
+                  .ClippedDrawingRectangleXMin = render_area->offset.x,
+                  .ClippedDrawingRectangleYMax =
+                     render_area->offset.y + render_area->extent.height - 1,
+                  .ClippedDrawingRectangleXMax =
+                     render_area->offset.x + render_area->extent.width - 1,
+                  .DrawingRectangleOriginY = 0,
+                  .DrawingRectangleOriginX = 0);
+
+   anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
+                                    pRenderPassBegin->pAttachmentClearValues);
+
+   gen8_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
+}
+
+void gen8_CmdNextSubpass(
+    VkCmdBuffer                                 cmdBuffer,
+    VkRenderPassContents                        contents)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   assert(cmd_buffer->level == VK_CMD_BUFFER_LEVEL_PRIMARY);
+
+   gen8_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
+}
+
+void gen8_CmdEndRenderPass(
+    VkCmdBuffer                                 cmdBuffer)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+
+   /* Emit a flushing pipe control at the end of a pass.  This is kind of a
+    * hack but it ensures that render targets always actually get written.
+    * Eventually, we should do flushing based on image format transitions
+    * or something of that nature.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                  .PostSyncOperation = NoWrite,
+                  .RenderTargetCacheFlushEnable = true,
+                  .InstructionCacheInvalidateEnable = true,
+                  .DepthCacheFlushEnable = true,
+                  .VFCacheInvalidationEnable = true,
+                  .TextureCacheInvalidationEnable = true,
+                  .CommandStreamerStallEnable = true);
+}
+
+static void
+emit_ps_depth_count(struct anv_batch *batch,
+                    struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_PIPE_CONTROL,
+                  .DestinationAddressType = DAT_PPGTT,
+                  .PostSyncOperation = WritePSDepthCount,
+                  .Address = { bo, offset });  /* FIXME: This is only lower 32 bits */
+}
+
+void gen8_CmdBeginQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot,
+    VkQueryControlFlags                         flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+
+   switch (pool->type) {
+   case VK_QUERY_TYPE_OCCLUSION:
+      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
+                                    slot * sizeof(struct anv_query_pool_slot));
+      break;
+
+   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+   default:
+      unreachable("");
+   }
+}
+
+void gen8_CmdEndQuery(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    slot)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+
+   switch (pool->type) {
+   case VK_QUERY_TYPE_OCCLUSION:
+      emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
+                          slot * sizeof(struct anv_query_pool_slot) + 8);
+      break;
+
+   case VK_QUERY_TYPE_PIPELINE_STATISTICS:
+   default:
+      unreachable("");
+   }
+}
+
+#define TIMESTAMP 0x2358
+
+void gen8_CmdWriteTimestamp(
+    VkCmdBuffer                                 cmdBuffer,
+    VkTimestampType                             timestampType,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
+   struct anv_bo *bo = buffer->bo;
+
+   switch (timestampType) {
+   case VK_TIMESTAMP_TYPE_TOP:
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = TIMESTAMP,
+                     .MemoryAddress = { bo, buffer->offset + destOffset });
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = TIMESTAMP + 4,
+                     .MemoryAddress = { bo, buffer->offset + destOffset + 4 });
+      break;
+
+   case VK_TIMESTAMP_TYPE_BOTTOM:
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                     .DestinationAddressType = DAT_PPGTT,
+                     .PostSyncOperation = WriteTimestamp,
+                     .Address = /* FIXME: This is only lower 32 bits */
+                        { bo, buffer->offset + destOffset });
+      break;
+
+   default:
+      break;
+   }
+}
+
+#define alu_opcode(v)   __gen_field((v),  20, 31)
+#define alu_operand1(v) __gen_field((v),  10, 19)
+#define alu_operand2(v) __gen_field((v),   0,  9)
+#define alu(opcode, operand1, operand2) \
+   alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
+
+#define OPCODE_NOOP      0x000
+#define OPCODE_LOAD      0x080
+#define OPCODE_LOADINV   0x480
+#define OPCODE_LOAD0     0x081
+#define OPCODE_LOAD1     0x481
+#define OPCODE_ADD       0x100
+#define OPCODE_SUB       0x101
+#define OPCODE_AND       0x102
+#define OPCODE_OR        0x103
+#define OPCODE_XOR       0x104
+#define OPCODE_STORE     0x180
+#define OPCODE_STOREINV  0x580
+
+#define OPERAND_R0   0x00
+#define OPERAND_R1   0x01
+#define OPERAND_R2   0x02
+#define OPERAND_R3   0x03
+#define OPERAND_R4   0x04
+#define OPERAND_SRCA 0x20
+#define OPERAND_SRCB 0x21
+#define OPERAND_ACCU 0x31
+#define OPERAND_ZF   0x32
+#define OPERAND_CF   0x33
+
+#define CS_GPR(n) (0x2600 + (n) * 8)
+
+static void
+emit_load_alu_reg_u64(struct anv_batch *batch, uint32_t reg,
+                      struct anv_bo *bo, uint32_t offset)
+{
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg,
+                  .MemoryAddress = { bo, offset });
+   anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
+                  .RegisterAddress = reg + 4,
+                  .MemoryAddress = { bo, offset + 4 });
+}
+
+void gen8_CmdCopyQueryPoolResults(
+    VkCmdBuffer                                 cmdBuffer,
+    VkQueryPool                                 queryPool,
+    uint32_t                                    startQuery,
+    uint32_t                                    queryCount,
+    VkBuffer                                    destBuffer,
+    VkDeviceSize                                destOffset,
+    VkDeviceSize                                destStride,
+    VkQueryResultFlags                          flags)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
+   ANV_FROM_HANDLE(anv_query_pool, pool, queryPool);
+   ANV_FROM_HANDLE(anv_buffer, buffer, destBuffer);
+   uint32_t slot_offset, dst_offset;
+
+   if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
+      /* Where is the availabilty info supposed to go? */
+      anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
+      return;
+   }
+
+   assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
+
+   /* FIXME: If we're not waiting, should we just do this on the CPU? */
+   if (flags & VK_QUERY_RESULT_WAIT_BIT)
+      anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                     .CommandStreamerStallEnable = true,
+                     .StallAtPixelScoreboard = true);
+
+   dst_offset = buffer->offset + destOffset;
+   for (uint32_t i = 0; i < queryCount; i++) {
+
+      slot_offset = (startQuery + i) * sizeof(struct anv_query_pool_slot);
+
+      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(0), &pool->bo, slot_offset);
+      emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(1), &pool->bo, slot_offset + 8);
+
+      /* FIXME: We need to clamp the result for 32 bit. */
+
+      uint32_t *dw = anv_batch_emitn(&cmd_buffer->batch, 5, GEN8_MI_MATH);
+      dw[1] = alu(OPCODE_LOAD, OPERAND_SRCA, OPERAND_R1);
+      dw[2] = alu(OPCODE_LOAD, OPERAND_SRCB, OPERAND_R0);
+      dw[3] = alu(OPCODE_SUB, 0, 0);
+      dw[4] = alu(OPCODE_STORE, OPERAND_R2, OPERAND_ACCU);
+
+      anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                     .RegisterAddress = CS_GPR(2),
+                     /* FIXME: This is only lower 32 bits */
+                     .MemoryAddress = { buffer->bo, dst_offset });
+
+      if (flags & VK_QUERY_RESULT_64_BIT)
+         anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
+                        .RegisterAddress = CS_GPR(2) + 4,
+                        /* FIXME: This is only lower 32 bits */
+                        .MemoryAddress = { buffer->bo, dst_offset + 4 });
+
+      dst_offset += destStride;
+   }
+}
+
+void
+gen8_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
+{
+   struct anv_device *device = cmd_buffer->device;
+   struct anv_bo *scratch_bo = NULL;
+
+   cmd_buffer->state.scratch_size =
+      anv_block_pool_size(&device->scratch_block_pool);
+   if (cmd_buffer->state.scratch_size > 0)
+      scratch_bo = &device->scratch_block_pool.bo;
+
+   anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
+                  .GeneralStateBaseAddress = { scratch_bo, 0 },
+                  .GeneralStateMemoryObjectControlState = GEN8_MOCS,
+                  .GeneralStateBaseAddressModifyEnable = true,
+                  .GeneralStateBufferSize = 0xfffff,
+                  .GeneralStateBufferSizeModifyEnable = true,
+
+                  .SurfaceStateBaseAddress = { anv_cmd_buffer_current_surface_bo(cmd_buffer), 0 },
+                  .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
+                  .SurfaceStateBaseAddressModifyEnable = true,
+
+                  .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
+                  .DynamicStateMemoryObjectControlState = GEN8_MOCS,
+                  .DynamicStateBaseAddressModifyEnable = true,
+                  .DynamicStateBufferSize = 0xfffff,
+                  .DynamicStateBufferSizeModifyEnable = true,
+
+                  .IndirectObjectBaseAddress = { NULL, 0 },
+                  .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
+                  .IndirectObjectBaseAddressModifyEnable = true,
+                  .IndirectObjectBufferSize = 0xfffff,
+                  .IndirectObjectBufferSizeModifyEnable = true,
+
+                  .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
+                  .InstructionMemoryObjectControlState = GEN8_MOCS,
+                  .InstructionBaseAddressModifyEnable = true,
+                  .InstructionBufferSize = 0xfffff,
+                  .InstructionBuffersizeModifyEnable = true);
+
+   /* After re-setting the surface state base address, we have to do some
+    * cache flusing so that the sampler engine will pick up the new
+    * SURFACE_STATE objects and binding tables. From the Broadwell PRM,
+    * Shared Function > 3D Sampler > State > State Caching (page 96):
+    *
+    *    Coherency with system memory in the state cache, like the texture
+    *    cache is handled partially by software. It is expected that the
+    *    command stream or shader will issue Cache Flush operation or
+    *    Cache_Flush sampler message to ensure that the L1 cache remains
+    *    coherent with system memory.
+    *
+    *    [...]
+    *
+    *    Whenever the value of the Dynamic_State_Base_Addr,
+    *    Surface_State_Base_Addr are altered, the L1 state cache must be
+    *    invalidated to ensure the new surface or sampler state is fetched
+    *    from system memory.
+    *
+    * The PIPE_CONTROL command has a "State Cache Invalidation Enable" bit
+    * which, according the PIPE_CONTROL instruction documentation in the
+    * Broadwell PRM:
+    *
+    *    Setting this bit is independent of any other bit in this packet.
+    *    This bit controls the invalidation of the L1 and L2 state caches
+    *    at the top of the pipe i.e. at the parsing time.
+    *
+    * Unfortunately, experimentation seems to indicate that state cache
+    * invalidation through a PIPE_CONTROL does nothing whatsoever in
+    * regards to surface state and binding tables.  In stead, it seems that
+    * invalidating the texture cache is what is actually needed.
+    *
+    * XXX:  As far as we have been able to determine through
+    * experimentation, shows that flush the texture cache appears to be
+    * sufficient.  The theory here is that all of the sampling/rendering
+    * units cache the binding table in the texture cache.  However, we have
+    * yet to be able to actually confirm this.
+    */
+   anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
+                  .TextureCacheInvalidationEnable = true);
+}
diff --git a/src/vulkan/gen8_pipeline.c b/src/vulkan/gen8_pipeline.c
new file mode 100644 (file)
index 0000000..0509183
--- /dev/null
@@ -0,0 +1,697 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+static void
+emit_vertex_input(struct anv_pipeline *pipeline,
+                  const VkPipelineVertexInputStateCreateInfo *info)
+{
+   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
+       * binding. Set up a map of which bindings step per instance, for
+       * reference by vertex element setup. */
+      switch (desc->stepRate) {
+      default:
+      case VK_VERTEX_INPUT_STEP_RATE_VERTEX:
+         instancing_enable[desc->binding] = false;
+         break;
+      case VK_VERTEX_INPUT_STEP_RATE_INSTANCE:
+         instancing_enable[desc->binding] = true;
+         break;
+      }
+   }
+
+   p = anv_batch_emitn(&pipeline->batch, num_dwords,
+                       GEN8_3DSTATE_VERTEX_ELEMENTS);
+
+   for (uint32_t i = 0; i < info->attributeCount; i++) {
+      const VkVertexInputAttributeDescription *desc =
+         &info->pVertexAttributeDescriptions[i];
+      const struct anv_format *format = anv_format_for_vk_format(desc->format);
+
+      struct GEN8_VERTEX_ELEMENT_STATE element = {
+         .VertexBufferIndex = desc->binding,
+         .Valid = true,
+         .SourceElementFormat = format->surface_format,
+         .EdgeFlagEnable = false,
+         .SourceElementOffset = desc->offsetInBytes,
+         .Component0Control = VFCOMP_STORE_SRC,
+         .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);
+
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_INSTANCING,
+                     .InstancingEnable = instancing_enable[desc->binding],
+                     .VertexElementIndex = i,
+                     /* Vulkan so far doesn't have an instance divisor, so
+                      * this is always 1 (ignored if not instancing). */
+                     .InstanceDataStepRate = 1);
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_SGVS,
+                  .VertexIDEnable = pipeline->vs_prog_data.uses_vertexid,
+                  .VertexIDComponentNumber = 2,
+                  .VertexIDElementOffset = info->bindingCount,
+                  .InstanceIDEnable = pipeline->vs_prog_data.uses_instanceid,
+                  .InstanceIDComponentNumber = 3,
+                  .InstanceIDElementOffset = info->bindingCount);
+}
+
+static void
+emit_ia_state(struct anv_pipeline *pipeline,
+              const VkPipelineInputAssemblyStateCreateInfo *info,
+              const struct anv_graphics_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_LINESTRIP_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
+   };
+   uint32_t topology = vk_to_gen_primitive_type[info->topology];
+
+   if (extra && extra->use_rectlist)
+      topology = _3DPRIM_RECTLIST;
+
+   struct GEN8_3DSTATE_VF vf = {
+      GEN8_3DSTATE_VF_header,
+      .IndexedDrawCutIndexEnable = info->primitiveRestartEnable,
+   };
+   GEN8_3DSTATE_VF_pack(NULL, pipeline->state_vf, &vf);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_VF_TOPOLOGY,
+                  .PrimitiveTopologyType = topology);
+}
+
+static void
+emit_rs_state(struct anv_pipeline *pipeline,
+              const VkPipelineRasterStateCreateInfo *info,
+              const struct anv_graphics_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
+   };
+
+   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
+   };
+
+   static const uint32_t vk_to_gen_front_face[] = {
+      [VK_FRONT_FACE_CCW]                       = CounterClockwise,
+      [VK_FRONT_FACE_CW]                        = Clockwise
+   };
+
+   struct GEN8_3DSTATE_SF sf = {
+      GEN8_3DSTATE_SF_header,
+      .ViewportTransformEnable = !(extra && extra->disable_viewport),
+      .TriangleStripListProvokingVertexSelect = 0,
+      .LineStripListProvokingVertexSelect = 0,
+      .TriangleFanProvokingVertexSelect = 0,
+      .PointWidthSource = pipeline->writes_point_size ? Vertex : State,
+      .PointWidth = 1.0,
+   };
+
+   /* FINISHME: VkBool32 rasterizerDiscardEnable; */
+
+   GEN8_3DSTATE_SF_pack(NULL, pipeline->state_sf, &sf);
+
+   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,
+                  .ForceVertexURBEntryReadOffset = false,
+                  .PointSpriteTextureCoordinateOrigin = UPPERLEFT,
+                  .NumberofSFOutputAttributes =
+                     pipeline->wm_prog_data.num_varying_inputs);
+
+}
+
+static void
+emit_cb_state(struct anv_pipeline *pipeline,
+              const VkPipelineColorBlendStateCreateInfo *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 = GEN8_BLEND_STATE_length;
+   pipeline->blend_state =
+      anv_state_pool_alloc(&device->dynamic_state_pool, num_dwords * 4, 64);
+
+   struct GEN8_BLEND_STATE blend_state = {
+      .AlphaToCoverageEnable = info->alphaToCoverageEnable,
+   };
+
+   for (uint32_t i = 0; i < info->attachmentCount; i++) {
+      const VkPipelineColorBlendAttachmentState *a = &info->pAttachments[i];
+
+      blend_state.Entry[i] = (struct GEN8_BLEND_STATE_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_pack(NULL, pipeline->blend_state.map, &blend_state);
+
+   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,
+              const VkPipelineDepthStencilStateCreateInfo *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;
+   }
+
+   /* VkBool32 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
+gen8_graphics_pipeline_create(
+    VkDevice                                    _device,
+    const VkGraphicsPipelineCreateInfo*         pCreateInfo,
+    const struct anv_graphics_pipeline_create_info *extra,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_pipeline *pipeline;
+   VkResult result;
+   uint32_t offset, length;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_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->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(pCreateInfo->layout);
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+
+   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);
+   pipeline->batch.relocs = &pipeline->batch_relocs;
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
+      pipeline->shaders[pCreateInfo->pStages[i].stage] =
+         anv_shader_from_handle(pCreateInfo->pStages[i].shader);
+   }
+
+   if (pCreateInfo->pTessellationState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO");
+   if (pCreateInfo->pViewportState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO");
+   if (pCreateInfo->pMultisampleState)
+      anv_finishme("VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO");
+
+   pipeline->use_repclear = extra && extra->use_repclear;
+
+   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 =
+         pCreateInfo->pVertexInputState->attributeCount - 2;
+   }
+
+   assert(pCreateInfo->pVertexInputState);
+   emit_vertex_input(pipeline, pCreateInfo->pVertexInputState);
+   assert(pCreateInfo->pInputAssemblyState);
+   emit_ia_state(pipeline, pCreateInfo->pInputAssemblyState, extra);
+   assert(pCreateInfo->pRasterState);
+   emit_rs_state(pipeline, pCreateInfo->pRasterState, extra);
+   emit_ds_state(pipeline, pCreateInfo->pDepthStencilState);
+   emit_cb_state(pipeline, pCreateInfo->pColorBlendState);
+
+   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),
+                  .MinimumPointWidth = 0.125,
+                  .MaximumPointWidth = 255.875);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_WM,
+                  .StatisticsEnable = true,
+                  .LineEndCapAntialiasingRegionWidth = _05pixels,
+                  .LineAntialiasingRegionWidth = _10pixels,
+                  .EarlyDepthStencilControl = NORMAL,
+                  .ForceThreadDispatchEnable = NORMAL,
+                  .PointRasterizationRule = RASTRULE_UPPER_RIGHT,
+                  .BarycentricInterpolationMode =
+                     pipeline->wm_prog_data.barycentric_interp_modes);
+
+   uint32_t samples = 1;
+   uint32_t log2_samples = __builtin_ffs(samples) - 1;
+   bool enable_sampling = samples > 1 ? true : false;
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_MULTISAMPLE,
+                  .PixelPositionOffsetEnable = enable_sampling,
+                  .PixelLocation = CENTER,
+                  .NumberofMultisamples = log2_samples);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_SAMPLE_MASK,
+                  .SampleMask = 0xffff);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_VS,
+                  .VSURBStartingAddress = pipeline->urb.vs_start,
+                  .VSURBEntryAllocationSize = pipeline->urb.vs_size - 1,
+                  .VSNumberofURBEntries = pipeline->urb.nr_vs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_GS,
+                  .GSURBStartingAddress = pipeline->urb.gs_start,
+                  .GSURBEntryAllocationSize = pipeline->urb.gs_size - 1,
+                  .GSNumberofURBEntries = pipeline->urb.nr_gs_entries);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_HS,
+                  .HSURBStartingAddress = pipeline->urb.vs_start,
+                  .HSURBEntryAllocationSize = 0,
+                  .HSNumberofURBEntries = 0);
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_URB_DS,
+                  .DSURBStartingAddress = pipeline->urb.vs_start,
+                  .DSURBEntryAllocationSize = 0,
+                  .DSNumberofURBEntries = 0);
+
+   const struct brw_gs_prog_data *gs_prog_data = &pipeline->gs_prog_data;
+   offset = 1;
+   length = (gs_prog_data->base.vue_map.num_slots + 1) / 2 - offset;
+
+   if (pipeline->gs_vec4 == NO_KERNEL)
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS, .Enable = false);
+   else
+      anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_GS,
+                     .SingleProgramFlow = false,
+                     .KernelStartPointer = pipeline->gs_vec4,
+                     .VectorMaskEnable = Vmask,
+                     .SamplerCount = 0,
+                     .BindingTableEntryCount = 0,
+                     .ExpectedVertexCount = pipeline->gs_vertex_count,
+
+                     .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,
+                     .VertexURBEntryReadLength = gs_prog_data->base.urb_read_length,
+                     .DispatchGRFStartRegisterForURBData =
+                        gs_prog_data->base.base.dispatch_grf_start_reg,
+
+                     .MaximumNumberofThreads = device->info.max_gs_threads,
+                     .ControlDataHeaderSize = gs_prog_data->control_data_header_size_hwords,
+                     //pipeline->gs_prog_data.dispatch_mode |
+                     .StatisticsEnable = true,
+                     .IncludePrimitiveID = gs_prog_data->include_primitive_id,
+                     .ReorderMode = TRAILING,
+                     .Enable = true,
+
+                     .ControlDataFormat = gs_prog_data->control_data_format,
+
+                     /* FIXME: mesa sets this based on ctx->Transform.ClipPlanesEnabled:
+                      * UserClipDistanceClipTestEnableBitmask_3DSTATE_GS(v)
+                      * UserClipDistanceCullTestEnableBitmask(v)
+                      */
+
+                     .VertexURBEntryOutputReadOffset = offset,
+                     .VertexURBEntryOutputLength = length);
+
+   const struct brw_vue_prog_data *vue_prog_data = &pipeline->vs_prog_data.base;
+   /* Skip the VUE header and position slots */
+   offset = 1;
+   length = (vue_prog_data->vue_map.num_slots + 1) / 2 - offset;
+
+   if (pipeline->vs_simd8 == NO_KERNEL || (extra && extra->disable_vs))
+      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(pCreateInfo->pVertexInputState->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,
+
+                     .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,
+                     .VertexURBEntryReadLength = vue_prog_data->urb_read_length,
+                     .VertexURBEntryReadOffset = 0,
+
+                     .MaximumNumberofThreads = device->info.max_vs_threads - 1,
+                     .StatisticsEnable = false,
+                     .SIMD8DispatchEnable = true,
+                     .VertexCacheDisable = false,
+                     .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;
+
+   ksp2 = 0;
+   grf_start2 = 0;
+   if (pipeline->ps_simd8 != NO_KERNEL) {
+      ksp0 = pipeline->ps_simd8;
+      grf_start0 = wm_prog_data->base.dispatch_grf_start_reg;
+      if (pipeline->ps_simd16 != NO_KERNEL) {
+         ksp2 = pipeline->ps_simd16;
+         grf_start2 = wm_prog_data->dispatch_grf_start_reg_16;
+      }
+   } else if (pipeline->ps_simd16 != NO_KERNEL) {
+      ksp0 = pipeline->ps_simd16;
+      grf_start0 = wm_prog_data->dispatch_grf_start_reg_16;
+   } else {
+      unreachable("no ps shader");
+   }
+
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS,
+                  .KernelStartPointer0 = ksp0,
+
+                  .SingleProgramFlow = false,
+                  .VectorMaskEnable = true,
+                  .SamplerCount = 1,
+
+                  .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 ?
+                     POSOFFSET_SAMPLE: POSOFFSET_NONE,
+                  .PushConstantEnable = wm_prog_data->base.nr_params > 0,
+                  ._8PixelDispatchEnable = pipeline->ps_simd8 != NO_KERNEL,
+                  ._16PixelDispatchEnable = pipeline->ps_simd16 != NO_KERNEL,
+                  ._32PixelDispatchEnable = false,
+
+                  .DispatchGRFStartRegisterForConstantSetupData0 = grf_start0,
+                  .DispatchGRFStartRegisterForConstantSetupData1 = 0,
+                  .DispatchGRFStartRegisterForConstantSetupData2 = grf_start2,
+
+                  .KernelStartPointer1 = 0,
+                  .KernelStartPointer2 = ksp2);
+
+   bool per_sample_ps = false;
+   anv_batch_emit(&pipeline->batch, GEN8_3DSTATE_PS_EXTRA,
+                  .PixelShaderValid = true,
+                  .PixelShaderKillsPixel = wm_prog_data->uses_kill,
+                  .PixelShaderComputedDepthMode = wm_prog_data->computed_depth_mode,
+                  .AttributeEnable = wm_prog_data->num_varying_inputs > 0,
+                  .oMaskPresenttoRenderTarget = wm_prog_data->uses_omask,
+                  .PixelShaderIsPerSample = per_sample_ps);
+
+   *pPipeline = anv_pipeline_to_handle(pipeline);
+
+   return VK_SUCCESS;
+}
+
+VkResult gen8_compute_pipeline_create(
+    VkDevice                                    _device,
+    const VkComputePipelineCreateInfo*          pCreateInfo,
+    VkPipeline*                                 pPipeline)
+{
+   ANV_FROM_HANDLE(anv_device, 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->device = device;
+   pipeline->layout = anv_pipeline_layout_from_handle(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);
+   pipeline->batch.relocs = &pipeline->batch_relocs;
+
+   anv_state_stream_init(&pipeline->program_stream,
+                         &device->instruction_block_pool);
+
+   memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+
+   pipeline->shaders[VK_SHADER_STAGE_COMPUTE] =
+      anv_shader_from_handle(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 = anv_pipeline_to_handle(pipeline);
+
+   return VK_SUCCESS;
+}
diff --git a/src/vulkan/gen8_state.c b/src/vulkan/gen8_state.c
new file mode 100644 (file)
index 0000000..d7078a2
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "anv_private.h"
+
+VkResult gen8_CreateDynamicRasterState(
+    VkDevice                                    _device,
+    const VkDynamicRasterStateCreateInfo*       pCreateInfo,
+    VkDynamicRasterState*                       pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_rs_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_3DSTATE_SF sf = {
+      GEN8_3DSTATE_SF_header,
+      .LineWidth = pCreateInfo->lineWidth,
+   };
+
+   GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
+
+   bool enable_bias = pCreateInfo->depthBias != 0.0f ||
+      pCreateInfo->slopeScaledDepthBias != 0.0f;
+   struct GEN8_3DSTATE_RASTER raster = {
+      .GlobalDepthOffsetEnableSolid = enable_bias,
+      .GlobalDepthOffsetEnableWireframe = enable_bias,
+      .GlobalDepthOffsetEnablePoint = enable_bias,
+      .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
+      .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
+      .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
+   };
+
+   GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
+
+   *pState = anv_dynamic_rs_state_to_handle(state);
+
+   return VK_SUCCESS;
+}
+
+void
+gen8_fill_buffer_surface_state(void *state, const struct anv_format *format,
+                               uint32_t offset, uint32_t range)
+{
+   /* This assumes RGBA float format. */
+   uint32_t stride = 4;
+   uint32_t num_elements = range / stride;
+
+   struct GEN8_RENDER_SURFACE_STATE surface_state = {
+      .SurfaceType = SURFTYPE_BUFFER,
+      .SurfaceArray = false,
+      .SurfaceFormat = format->surface_format,
+      .SurfaceVerticalAlignment = VALIGN4,
+      .SurfaceHorizontalAlignment = HALIGN4,
+      .TileMode = LINEAR,
+      .VerticalLineStride = 0,
+      .VerticalLineStrideOffset = 0,
+      .SamplerL2BypassModeDisable = true,
+      .RenderCacheReadWriteMode = WriteOnlyCache,
+      .MemoryObjectControlState = GEN8_MOCS,
+      .BaseMipLevel = 0.0,
+      .SurfaceQPitch = 0,
+      .Height = (num_elements >> 7) & 0x3fff,
+      .Width = num_elements & 0x7f,
+      .Depth = (num_elements >> 21) & 0x3f,
+      .SurfacePitch = stride - 1,
+      .MinimumArrayElement = 0,
+      .NumberofMultisamples = MULTISAMPLECOUNT_1,
+      .XOffset = 0,
+      .YOffset = 0,
+      .SurfaceMinLOD = 0,
+      .MIPCountLOD = 0,
+      .AuxiliarySurfaceMode = AUX_NONE,
+      .RedClearColor = 0,
+      .GreenClearColor = 0,
+      .BlueClearColor = 0,
+      .AlphaClearColor = 0,
+      .ShaderChannelSelectRed = SCS_RED,
+      .ShaderChannelSelectGreen = SCS_GREEN,
+      .ShaderChannelSelectBlue = SCS_BLUE,
+      .ShaderChannelSelectAlpha = SCS_ALPHA,
+      .ResourceMinLOD = 0.0,
+      /* FIXME: We assume that the image must be bound at this time. */
+      .SurfaceBaseAddress = { NULL, offset },
+   };
+
+   GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
+}
+
+VkResult gen8_CreateBufferView(
+    VkDevice                                    _device,
+    const VkBufferViewCreateInfo*               pCreateInfo,
+    VkBufferView*                               pView)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_buffer_view *view;
+   VkResult result;
+
+   result = anv_buffer_view_create(device, pCreateInfo, &view);
+   if (result != VK_SUCCESS)
+      return result;
+
+   const struct anv_format *format =
+      anv_format_for_vk_format(pCreateInfo->format);
+
+   gen8_fill_buffer_surface_state(view->view.surface_state.map, format,
+                                  view->view.offset, pCreateInfo->range);
+
+   *pView = anv_buffer_view_to_handle(view);
+
+   return VK_SUCCESS;
+}
+
+VkResult gen8_CreateSampler(
+    VkDevice                                    _device,
+    const VkSamplerCreateInfo*                  pCreateInfo,
+    VkSampler*                                  pSampler)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_sampler *sampler;
+   uint32_t mag_filter, min_filter, max_anisotropy;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+
+   sampler = anv_device_alloc(device, sizeof(*sampler), 8,
+                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!sampler)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   static const uint32_t vk_to_gen_tex_filter[] = {
+      [VK_TEX_FILTER_NEAREST]                   = MAPFILTER_NEAREST,
+      [VK_TEX_FILTER_LINEAR]                    = MAPFILTER_LINEAR
+   };
+
+   static const uint32_t vk_to_gen_mipmap_mode[] = {
+      [VK_TEX_MIPMAP_MODE_BASE]                 = MIPFILTER_NONE,
+      [VK_TEX_MIPMAP_MODE_NEAREST]              = MIPFILTER_NEAREST,
+      [VK_TEX_MIPMAP_MODE_LINEAR]               = MIPFILTER_LINEAR
+   };
+
+   static const uint32_t vk_to_gen_tex_address[] = {
+      [VK_TEX_ADDRESS_WRAP]                     = TCM_WRAP,
+      [VK_TEX_ADDRESS_MIRROR]                   = TCM_MIRROR,
+      [VK_TEX_ADDRESS_CLAMP]                    = TCM_CLAMP,
+      [VK_TEX_ADDRESS_MIRROR_ONCE]              = TCM_MIRROR_ONCE,
+      [VK_TEX_ADDRESS_CLAMP_BORDER]             = TCM_CLAMP_BORDER,
+   };
+
+   static const uint32_t vk_to_gen_compare_op[] = {
+      [VK_COMPARE_OP_NEVER]                     = PREFILTEROPNEVER,
+      [VK_COMPARE_OP_LESS]                      = PREFILTEROPLESS,
+      [VK_COMPARE_OP_EQUAL]                     = PREFILTEROPEQUAL,
+      [VK_COMPARE_OP_LESS_EQUAL]                = PREFILTEROPLEQUAL,
+      [VK_COMPARE_OP_GREATER]                   = PREFILTEROPGREATER,
+      [VK_COMPARE_OP_NOT_EQUAL]                 = PREFILTEROPNOTEQUAL,
+      [VK_COMPARE_OP_GREATER_EQUAL]             = PREFILTEROPGEQUAL,
+      [VK_COMPARE_OP_ALWAYS]                    = PREFILTEROPALWAYS,
+   };
+
+   if (pCreateInfo->maxAnisotropy > 1) {
+      mag_filter = MAPFILTER_ANISOTROPIC;
+      min_filter = MAPFILTER_ANISOTROPIC;
+      max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
+   } else {
+      mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
+      min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
+      max_anisotropy = RATIO21;
+   }
+
+   struct GEN8_SAMPLER_STATE sampler_state = {
+      .SamplerDisable = false,
+      .TextureBorderColorMode = DX10OGL,
+      .LODPreClampMode = 0,
+      .BaseMipLevel = 0.0,
+      .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
+      .MagModeFilter = mag_filter,
+      .MinModeFilter = min_filter,
+      .TextureLODBias = pCreateInfo->mipLodBias * 256,
+      .AnisotropicAlgorithm = EWAApproximation,
+      .MinLOD = pCreateInfo->minLod,
+      .MaxLOD = pCreateInfo->maxLod,
+      .ChromaKeyEnable = 0,
+      .ChromaKeyIndex = 0,
+      .ChromaKeyMode = 0,
+      .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
+      .CubeSurfaceControlMode = 0,
+
+      .IndirectStatePointer =
+         device->border_colors.offset +
+         pCreateInfo->borderColor * sizeof(float) * 4,
+
+      .LODClampMagnificationMode = MIPNONE,
+      .MaximumAnisotropy = max_anisotropy,
+      .RAddressMinFilterRoundingEnable = 0,
+      .RAddressMagFilterRoundingEnable = 0,
+      .VAddressMinFilterRoundingEnable = 0,
+      .VAddressMagFilterRoundingEnable = 0,
+      .UAddressMinFilterRoundingEnable = 0,
+      .UAddressMagFilterRoundingEnable = 0,
+      .TrilinearFilterQuality = 0,
+      .NonnormalizedCoordinateEnable = 0,
+      .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
+      .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
+      .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
+   };
+
+   GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
+
+   *pSampler = anv_sampler_to_handle(sampler);
+
+   return VK_SUCCESS;
+}
+
+VkResult gen8_CreateDynamicDepthStencilState(
+    VkDevice                                    _device,
+    const VkDynamicDepthStencilStateCreateInfo* pCreateInfo,
+    VkDynamicDepthStencilState*                 pState)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   struct anv_dynamic_ds_state *state;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO);
+
+   state = anv_device_alloc(device, sizeof(*state), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (state == NULL)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
+      GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
+
+      /* Is this what we need to do? */
+      .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
+
+      .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
+      .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
+
+      .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
+      .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
+   };
+
+   GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
+                                      &wm_depth_stencil);
+
+   struct GEN8_COLOR_CALC_STATE color_calc_state = {
+      .StencilReferenceValue = pCreateInfo->stencilFrontRef,
+      .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
+   };
+
+   GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
+
+   *pState = anv_dynamic_ds_state_to_handle(state);
+
+   return VK_SUCCESS;
+}