diff options
author | Jason Ekstrand <jason@jlekstrand.net> | 2020-10-04 09:15:36 -0500 |
---|---|---|
committer | Marge Bot <eric+marge@anholt.net> | 2020-10-05 22:34:07 +0000 |
commit | d82826ad44465423407d1e4413d7d66bee82737c (patch) | |
tree | e1d36e1d7b4463b5fb87f6e1e35f3003309dbdfb /src/intel/vulkan/genX_pipeline.c | |
parent | 9831888b68207acb4e1410c7960cd9e675cad603 (diff) |
anv: Implement VK_EXT_transform_feedback on Gen7
Things work a little different on Gen7 than they do on Gen8+. In
particular, SOBufferEnable lives in 3DSTATE_STREAMOUT but BufferPitch
lives in 3DSTATE_SO_BUFFER. This leaves us having to marshal data
around a bit more than we did on Gen8. Still, it's not too bad.
Normally, I don't spend much time on Gen7 but XFB just became a hard
requirement for DXVK so it stopped working for all our Haswell users.
Let's get them happily playing their games again. 😸
Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/3532
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6997>
Diffstat (limited to 'src/intel/vulkan/genX_pipeline.c')
-rw-r--r-- | src/intel/vulkan/genX_pipeline.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c index d4b93688da1..205e8677f19 100644 --- a/src/intel/vulkan/genX_pipeline.c +++ b/src/intel/vulkan/genX_pipeline.c @@ -1370,7 +1370,6 @@ static void emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, const VkPipelineRasterizationStateCreateInfo *rs_info) { -#if GEN_GEN >= 8 const struct brw_vue_prog_data *prog_data = anv_pipeline_get_last_vue_prog_data(pipeline); const struct brw_vue_map *vue_map = &prog_data->vue_map; @@ -1382,12 +1381,10 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, xfb_info = pipeline->shaders[MESA_SHADER_TESS_EVAL]->xfb_info; else xfb_info = pipeline->shaders[MESA_SHADER_VERTEX]->xfb_info; -#endif anv_batch_emit(&pipeline->base.batch, GENX(3DSTATE_STREAMOUT), so) { so.RenderingDisable = rs_info->rasterizerDiscardEnable; -#if GEN_GEN >= 8 if (xfb_info) { so.SOFunctionEnable = true; so.SOStatisticsEnable = true; @@ -1397,10 +1394,28 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, so.RenderStreamSelect = stream_info ? stream_info->rasterizationStream : 0; +#if GEN_GEN >= 8 so.Buffer0SurfacePitch = xfb_info->buffers[0].stride; so.Buffer1SurfacePitch = xfb_info->buffers[1].stride; so.Buffer2SurfacePitch = xfb_info->buffers[2].stride; so.Buffer3SurfacePitch = xfb_info->buffers[3].stride; +#else + pipeline->gen7.xfb_bo_pitch[0] = xfb_info->buffers[0].stride; + pipeline->gen7.xfb_bo_pitch[1] = xfb_info->buffers[1].stride; + pipeline->gen7.xfb_bo_pitch[2] = xfb_info->buffers[2].stride; + pipeline->gen7.xfb_bo_pitch[3] = xfb_info->buffers[3].stride; + + /* On Gen7, the SO buffer enables live in 3DSTATE_STREAMOUT which + * is a bit inconvenient because we don't know what buffers will + * actually be enabled until draw time. We do our best here by + * setting them based on buffers_written and we disable them + * as-needed at draw time by setting EndAddress = BaseAddress. + */ + so.SOBufferEnable0 = xfb_info->buffers_written & (1 << 0); + so.SOBufferEnable1 = xfb_info->buffers_written & (1 << 1); + so.SOBufferEnable2 = xfb_info->buffers_written & (1 << 2); + so.SOBufferEnable3 = xfb_info->buffers_written & (1 << 3); +#endif int urb_entry_read_offset = 0; int urb_entry_read_length = @@ -1419,10 +1434,8 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, so.Stream3VertexReadOffset = urb_entry_read_offset; so.Stream3VertexReadLength = urb_entry_read_length - 1; } -#endif /* GEN_GEN >= 8 */ } -#if GEN_GEN >= 8 if (xfb_info) { struct GENX(SO_DECL) so_decl[MAX_XFB_STREAMS][128]; int next_offset[MAX_XFB_BUFFERS] = {0, 0, 0, 0}; @@ -1521,7 +1534,6 @@ emit_3dstate_streamout(struct anv_graphics_pipeline *pipeline, }); } } -#endif /* GEN_GEN >= 8 */ } static uint32_t |