anv_batch_emit(batch, GEN7_PIPE_CONTROL, pc) {
pc.DepthStallEnable = true;
pc.PostSyncOperation = WriteImmediateData;
- pc.Address = (struct anv_address) { &device->workaround_bo, 0 };
+ pc.Address = (struct anv_address) { device->workaround_bo, 0 };
}
#endif
[VK_FRONT_FACE_CLOCKWISE] = 0
};
+static VkLineRasterizationModeEXT
+vk_line_rasterization_mode(const VkPipelineRasterizationLineStateCreateInfoEXT *line_info,
+ const VkPipelineMultisampleStateCreateInfo *ms_info)
+{
+ VkLineRasterizationModeEXT line_mode =
+ line_info ? line_info->lineRasterizationMode :
+ VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
+
+ if (line_mode == VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) {
+ if (ms_info && ms_info->rasterizationSamples > 1) {
+ return VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
+ } else {
+ return VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
+ }
+ }
+
+ return line_mode;
+}
+
/** Returns the final polygon mode for rasterization
*
* This function takes into account polygon mode, primitive topology and the
const VkPipelineInputAssemblyStateCreateInfo *ia_info,
const VkPipelineRasterizationStateCreateInfo *rs_info)
{
- /* Points always override everything. This saves us from having to handle
- * rs_info->polygonMode in all of the line cases below.
- */
- if (rs_info->polygonMode == VK_POLYGON_MODE_POINT)
- return VK_POLYGON_MODE_POINT;
-
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_GEOMETRY)) {
switch (get_gs_prog_data(pipeline)->output_topology) {
case _3DPRIM_POINTLIST:
}
}
+#if GEN_GEN <= 7
+static uint32_t
+gen7_ms_rast_mode(struct anv_pipeline *pipeline,
+ const VkPipelineInputAssemblyStateCreateInfo *ia_info,
+ const VkPipelineRasterizationStateCreateInfo *rs_info,
+ const VkPipelineMultisampleStateCreateInfo *ms_info)
+{
+ const VkPipelineRasterizationLineStateCreateInfoEXT *line_info =
+ vk_find_struct_const(rs_info->pNext,
+ PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+
+ VkPolygonMode raster_mode =
+ anv_raster_polygon_mode(pipeline, ia_info, rs_info);
+ if (raster_mode == VK_POLYGON_MODE_LINE) {
+ switch (vk_line_rasterization_mode(line_info, ms_info)) {
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
+ return MSRASTMODE_ON_PATTERN;
+
+ case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
+ return MSRASTMODE_OFF_PIXEL;
+
+ default:
+ unreachable("Unsupported line rasterization mode");
+ }
+ } else {
+ return (ms_info && ms_info->rasterizationSamples > 1) ?
+ MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
+ }
+}
+#endif
+
static void
emit_rs_state(struct anv_pipeline *pipeline,
+ const VkPipelineInputAssemblyStateCreateInfo *ia_info,
const VkPipelineRasterizationStateCreateInfo *rs_info,
const VkPipelineMultisampleStateCreateInfo *ms_info,
+ const VkPipelineRasterizationLineStateCreateInfoEXT *line_info,
const struct anv_render_pass *pass,
const struct anv_subpass *subpass)
{
sf.LineStripListProvokingVertexSelect = 0;
sf.TriangleFanProvokingVertexSelect = 1;
sf.VertexSubPixelPrecisionSelect = _8Bit;
+ sf.AALineDistanceMode = true;
+
+#if GEN_IS_HASWELL
+ sf.LineStippleEnable = line_info && line_info->stippledLineEnable;
+#endif
const struct brw_vue_prog_data *last_vue_prog_data =
anv_pipeline_get_last_vue_prog_data(pipeline);
# define raster sf
#endif
+ VkPolygonMode raster_mode =
+ anv_raster_polygon_mode(pipeline, ia_info, rs_info);
+ VkLineRasterizationModeEXT line_mode =
+ vk_line_rasterization_mode(line_info, ms_info);
+
/* For details on 3DSTATE_RASTER multisample state, see the BSpec table
* "Multisample Modes State".
*/
#if GEN_GEN >= 8
- raster.DXMultisampleRasterizationEnable = true;
+ if (raster_mode == VK_POLYGON_MODE_LINE) {
+ /* Unfortunately, configuring our line rasterization hardware on gen8
+ * and later is rather painful. Instead of giving us bits to tell the
+ * hardware what line mode to use like we had on gen7, we now have an
+ * arcane combination of API Mode and MSAA enable bits which do things
+ * in a table which are expected to magically put the hardware into the
+ * right mode for your API. Sadly, Vulkan isn't any of the APIs the
+ * hardware people thought of so nothing works the way you want it to.
+ *
+ * Look at the table titled "Multisample Rasterization Modes" in Vol 7
+ * of the Skylake PRM for more details.
+ */
+ switch (line_mode) {
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT:
+ raster.APIMode = DX100;
+ raster.DXMultisampleRasterizationEnable = true;
+ break;
+
+ case VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT:
+ case VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT:
+ raster.APIMode = DX9OGL;
+ raster.DXMultisampleRasterizationEnable = false;
+ break;
+
+ default:
+ unreachable("Unsupported line rasterization mode");
+ }
+ } else {
+ raster.APIMode = DX100;
+ raster.DXMultisampleRasterizationEnable = true;
+ }
+
/* NOTE: 3DSTATE_RASTER::ForcedSampleCount affects the BDW and SKL PMA fix
* computations. If we ever set this bit to a different value, they will
* need to be updated accordingly.
raster.ForceMultisampling = false;
#else
raster.MultisampleRasterizationMode =
- (ms_info && ms_info->rasterizationSamples > 1) ?
- MSRASTMODE_ON_PATTERN : MSRASTMODE_OFF_PIXEL;
+ gen7_ms_rast_mode(pipeline, ia_info, rs_info, ms_info);
#endif
+ if (raster_mode == VK_POLYGON_MODE_LINE &&
+ line_mode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT)
+ raster.AntialiasingEnable = true;
+
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];
pipeline->stencil_test_enable = false;
pipeline->writes_depth = false;
pipeline->depth_test_enable = false;
+ pipeline->depth_bounds_test_enable = false;
memset(depth_stencil_dw, 0, sizeof(depth_stencil_dw));
return;
}
pipeline->stencil_test_enable = info.stencilTestEnable;
pipeline->writes_depth = info.depthWriteEnable;
pipeline->depth_test_enable = info.depthTestEnable;
-
- /* VkBool32 depthBoundsTestEnable; // optional (depth_bounds_test) */
+ pipeline->depth_bounds_test_enable = info.depthBoundsTestEnable;
#if GEN_GEN <= 7
struct GENX(DEPTH_STENCIL_STATE) depth_stencil = {
#endif
}
-MAYBE_UNUSED static bool
+static bool
is_dual_src_blend_factor(VkBlendFactor factor)
{
return factor == VK_BLEND_FACTOR_SRC1_COLOR ||
continue;
}
- assert(binding->binding == 0);
const VkPipelineColorBlendAttachmentState *a =
&info->pAttachments[binding->index];
static void
emit_3dstate_wm(struct anv_pipeline *pipeline, struct anv_subpass *subpass,
+ const VkPipelineInputAssemblyStateCreateInfo *ia,
+ const VkPipelineRasterizationStateCreateInfo *raster,
const VkPipelineColorBlendStateCreateInfo *blend,
- const VkPipelineMultisampleStateCreateInfo *multisample)
+ const VkPipelineMultisampleStateCreateInfo *multisample,
+ const VkPipelineRasterizationLineStateCreateInfoEXT *line)
{
const struct brw_wm_prog_data *wm_prog_data = get_wm_prog_data(pipeline);
- MAYBE_UNUSED uint32_t samples =
- multisample ? multisample->rasterizationSamples : 1;
-
anv_batch_emit(&pipeline->batch, GENX(3DSTATE_WM), wm) {
wm.StatisticsEnable = true;
wm.LineEndCapAntialiasingRegionWidth = _05pixels;
has_color_buffer_write_enabled(pipeline, blend))
wm.ThreadDispatchEnable = true;
- if (samples > 1) {
- wm.MultisampleRasterizationMode = MSRASTMODE_ON_PATTERN;
+ if (multisample && multisample->rasterizationSamples > 1) {
if (wm_prog_data->persample_dispatch) {
wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE;
} else {
wm.MultisampleDispatchMode = MSDISPMODE_PERPIXEL;
}
} else {
- wm.MultisampleRasterizationMode = MSRASTMODE_OFF_PIXEL;
wm.MultisampleDispatchMode = MSDISPMODE_PERSAMPLE;
}
+ wm.MultisampleRasterizationMode =
+ gen7_ms_rast_mode(pipeline, ia, raster, multisample);
#endif
+
+ wm.LineStippleEnable = line && line->stippledLineEnable;
}
}
}
const VkPipelineColorBlendStateCreateInfo *blend,
const VkPipelineMultisampleStateCreateInfo *multisample)
{
- MAYBE_UNUSED const struct gen_device_info *devinfo = &pipeline->device->info;
+ UNUSED const struct gen_device_info *devinfo = &pipeline->device->info;
const struct anv_shader_bin *fs_bin =
pipeline->shaders[MESA_SHADER_FRAGMENT];
return result;
}
+ const VkPipelineRasterizationLineStateCreateInfoEXT *line_info =
+ vk_find_struct_const(pCreateInfo->pRasterizationState->pNext,
+ PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
+
assert(pCreateInfo->pVertexInputState);
emit_vertex_input(pipeline, pCreateInfo->pVertexInputState);
assert(pCreateInfo->pRasterizationState);
- emit_rs_state(pipeline, pCreateInfo->pRasterizationState,
- pCreateInfo->pMultisampleState, pass, subpass);
+ emit_rs_state(pipeline, pCreateInfo->pInputAssemblyState,
+ pCreateInfo->pRasterizationState,
+ pCreateInfo->pMultisampleState,
+ line_info, pass, subpass);
emit_ms_state(pipeline, pCreateInfo->pMultisampleState);
emit_ds_state(pipeline, pCreateInfo->pDepthStencilState, pass, subpass);
emit_cb_state(pipeline, pCreateInfo->pColorBlendState,
emit_3dstate_hs_te_ds(pipeline, pCreateInfo->pTessellationState);
emit_3dstate_gs(pipeline);
emit_3dstate_sbe(pipeline);
- emit_3dstate_wm(pipeline, subpass, pCreateInfo->pColorBlendState,
- pCreateInfo->pMultisampleState);
+ emit_3dstate_wm(pipeline, subpass,
+ pCreateInfo->pInputAssemblyState,
+ pCreateInfo->pRasterizationState,
+ pCreateInfo->pColorBlendState,
+ pCreateInfo->pMultisampleState, line_info);
emit_3dstate_ps(pipeline, pCreateInfo->pColorBlendState,
pCreateInfo->pMultisampleState);
#if GEN_GEN >= 8
pipeline->blend_state.map = NULL;
- result = anv_reloc_list_init(&pipeline->batch_relocs,
- pAllocator ? pAllocator : &device->alloc);
+ const VkAllocationCallbacks *alloc =
+ pAllocator ? pAllocator : &device->alloc;
+
+ result = anv_reloc_list_init(&pipeline->batch_relocs, alloc);
if (result != VK_SUCCESS) {
vk_free2(&device->alloc, pAllocator, pipeline);
return result;
}
+ pipeline->batch.alloc = alloc;
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;
pipeline->batch.status = VK_SUCCESS;
+ pipeline->mem_ctx = ralloc_context(NULL);
+ pipeline->flags = pCreateInfo->flags;
+
/* When we free the pipeline, we detect stages based on the NULL status
* of various prog_data pointers. Make them NULL by default.
*/
memset(pipeline->shaders, 0, sizeof(pipeline->shaders));
+ pipeline->num_executables = 0;
pipeline->needs_data_cache = false;
pCreateInfo->stage.pName,
pCreateInfo->stage.pSpecializationInfo);
if (result != VK_SUCCESS) {
+ ralloc_free(pipeline->mem_ctx);
vk_free2(&device->alloc, pAllocator, pipeline);
return result;
}