anv: pipeline: gen7: fix assert in debug mode
[mesa.git] / src / intel / vulkan / genX_pipeline_util.h
index c134d5da5a7005026ebacf77196f73811b582bba..679fb5768351370674b307c9ff2da97615e6718c 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include "vk_format_info.h"
+#include "genX_multisample.h"
 
 static uint32_t
 vertex_element_comp_control(enum isl_format format, unsigned comp)
@@ -362,6 +363,158 @@ static const uint32_t vk_to_gen_front_face[] = {
    [VK_FRONT_FACE_CLOCKWISE]                 = 0
 };
 
+static void
+emit_rs_state(struct anv_pipeline *pipeline,
+              const VkPipelineRasterizationStateCreateInfo *rs_info,
+              const VkPipelineMultisampleStateCreateInfo *ms_info,
+              const struct anv_render_pass *pass,
+              const struct anv_subpass *subpass,
+              const struct anv_graphics_pipeline_create_info *extra)
+{
+   struct GENX(3DSTATE_SF) sf = {
+      GENX(3DSTATE_SF_header),
+   };
+
+   sf.ViewportTransformEnable = !(extra && extra->use_rectlist);
+   sf.StatisticsEnable = true;
+   sf.TriangleStripListProvokingVertexSelect = 0;
+   sf.LineStripListProvokingVertexSelect = 0;
+   sf.TriangleFanProvokingVertexSelect = 1;
+   sf.PointWidthSource = Vertex;
+   sf.PointWidth = 1.0;
+
+#if GEN_GEN >= 8
+   struct GENX(3DSTATE_RASTER) raster = {
+      GENX(3DSTATE_RASTER_header),
+   };
+#else
+#  define raster sf
+#endif
+
+   /* For details on 3DSTATE_RASTER multisample state, see the BSpec table
+    * "Multisample Modes State".
+    */
+#if GEN_GEN >= 8
+   raster.DXMultisampleRasterizationEnable = true;
+   raster.ForcedSampleCount = FSC_NUMRASTSAMPLES_0;
+   raster.ForceMultisampling = false;
+#else
+   raster.MultisampleRasterizationMode =
+      (ms_info && ms_info->rasterizationSamples > 1) ?
+      MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
+#endif
+
+   raster.FrontWinding = vk_to_gen_front_face[rs_info->frontFace];
+   raster.CullMode = vk_to_gen_cullmode[rs_info->cullMode];
+   raster.FrontFaceFillMode = vk_to_gen_fillmode[rs_info->polygonMode];
+   raster.BackFaceFillMode = vk_to_gen_fillmode[rs_info->polygonMode];
+   raster.ScissorRectangleEnable = !(extra && extra->use_rectlist);
+
+#if GEN_GEN >= 9
+   /* GEN9+ splits ViewportZClipTestEnable into near and far enable bits */
+   raster.ViewportZFarClipTestEnable = !pipeline->depth_clamp_enable;
+   raster.ViewportZNearClipTestEnable = !pipeline->depth_clamp_enable;
+#elif GEN_GEN >= 8
+   raster.ViewportZClipTestEnable = !pipeline->depth_clamp_enable;
+#endif
+
+   raster.GlobalDepthOffsetEnableSolid = rs_info->depthBiasEnable;
+   raster.GlobalDepthOffsetEnableWireframe = rs_info->depthBiasEnable;
+   raster.GlobalDepthOffsetEnablePoint = rs_info->depthBiasEnable;
+
+#if GEN_GEN == 7
+   /* Gen7 requires that we provide the depth format in 3DSTATE_SF so that it
+    * can get the depth offsets correct.
+    */
+   if (subpass->depth_stencil_attachment < pass->attachment_count) {
+      VkFormat vk_format =
+         pass->attachments[subpass->depth_stencil_attachment].format;
+      assert(vk_format_is_depth_or_stencil(vk_format));
+      if (vk_format_aspects(vk_format) & VK_IMAGE_ASPECT_DEPTH_BIT) {
+         enum isl_format isl_format =
+            anv_get_isl_format(&pipeline->device->info, vk_format,
+                               VK_IMAGE_ASPECT_DEPTH_BIT,
+                               VK_IMAGE_TILING_OPTIMAL);
+         sf.DepthBufferSurfaceFormat =
+            isl_format_get_depth_format(isl_format, false);
+      }
+   }
+#endif
+
+#if GEN_GEN >= 8
+   GENX(3DSTATE_SF_pack)(NULL, pipeline->gen8.sf, &sf);
+   GENX(3DSTATE_RASTER_pack)(NULL, pipeline->gen8.raster, &raster);
+#else
+#  undef raster
+   GENX(3DSTATE_SF_pack)(NULL, &pipeline->gen7.sf, &sf);
+#endif
+}
+
+static void
+emit_ms_state(struct anv_pipeline *pipeline,
+              const VkPipelineMultisampleStateCreateInfo *info)
+{
+   uint32_t samples = 1;
+   uint32_t log2_samples = 0;
+
+   /* From the Vulkan 1.0 spec:
+    *    If pSampleMask is NULL, it is treated as if the mask has all bits
+    *    enabled, i.e. no coverage is removed from fragments.
+    *
+    * 3DSTATE_SAMPLE_MASK.SampleMask is 16 bits.
+    */
+#if GEN_GEN >= 8
+   uint32_t sample_mask = 0xffff;
+#else
+   uint32_t sample_mask = 0xff;
+#endif
+
+   if (info) {
+      samples = info->rasterizationSamples;
+      log2_samples = __builtin_ffs(samples) - 1;
+   }
+
+   if (info && info->pSampleMask)
+      sample_mask &= info->pSampleMask[0];
+
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_MULTISAMPLE), ms) {
+      ms.NumberofMultisamples       = log2_samples;
+
+#if GEN_GEN >= 8
+      /* The PRM says that this bit is valid only for DX9:
+       *
+       *    SW can choose to set this bit only for DX9 API. DX10/OGL API's
+       *    should not have any effect by setting or not setting this bit.
+       */
+      ms.PixelPositionOffsetEnable  = false;
+      ms.PixelLocation              = CENTER;
+#else
+      ms.PixelLocation              = PIXLOC_CENTER;
+
+      switch (samples) {
+      case 1:
+         SAMPLE_POS_1X(ms.Sample);
+         break;
+      case 2:
+         SAMPLE_POS_2X(ms.Sample);
+         break;
+      case 4:
+         SAMPLE_POS_4X(ms.Sample);
+         break;
+      case 8:
+         SAMPLE_POS_8X(ms.Sample);
+         break;
+      default:
+         break;
+      }
+#endif
+   }
+
+   anv_batch_emit(&pipeline->batch, GENX(3DSTATE_SAMPLE_MASK), sm) {
+      sm.SampleMask = sample_mask;
+   }
+}
+
 static const uint32_t vk_to_gen_logic_op[] = {
    [VK_LOGIC_OP_COPY]                        = LOGICOP_COPY,
    [VK_LOGIC_OP_CLEAR]                       = LOGICOP_CLEAR,