diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:13:23 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:13:23 +0000 |
commit | d21826c357bdc90ceabf91f368bd545cbe40c3e9 (patch) | |
tree | 2196440b7866e61a44af62a5e459f2a129a33b4d /lib/mesa/src | |
parent | 51a0616dc513335458f256ef9b5bf03f4256ad58 (diff) |
Import Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src')
-rw-r--r-- | lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c | 257 |
1 files changed, 125 insertions, 132 deletions
diff --git a/lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c b/lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c index d05c9370c..b08bcf34b 100644 --- a/lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c +++ b/lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c @@ -34,9 +34,98 @@ #include "genxml/genX_pack.h" #if GFX_VERx10 == 70 +static int64_t +clamp_int64(int64_t x, int64_t min, int64_t max) +{ + if (x < min) + return min; + else if (x < max) + return x; + else + return max; +} + +void +gfx7_cmd_buffer_emit_scissor(struct anv_cmd_buffer *cmd_buffer) +{ + struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; + uint32_t count = cmd_buffer->state.gfx.dynamic.scissor.count; + const VkRect2D *scissors = cmd_buffer->state.gfx.dynamic.scissor.scissors; + + /* Wa_1409725701: + * "The viewport-specific state used by the SF unit (SCISSOR_RECT) is + * stored as an array of up to 16 elements. The location of first + * element of the array, as specified by Pointer to SCISSOR_RECT, should + * be aligned to a 64-byte boundary. + */ + uint32_t alignment = 64; + struct anv_state scissor_state = + anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, count * 8, alignment); + + for (uint32_t i = 0; i < count; i++) { + const VkRect2D *s = &scissors[i]; + + /* Since xmax and ymax are inclusive, we have to have xmax < xmin or + * ymax < ymin for empty clips. In case clip x, y, width height are all + * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't + * what we want. Just special case empty clips and produce a canonical + * empty clip. */ + static const struct GFX7_SCISSOR_RECT empty_scissor = { + .ScissorRectangleYMin = 1, + .ScissorRectangleXMin = 1, + .ScissorRectangleYMax = 0, + .ScissorRectangleXMax = 0 + }; + + const int max = 0xffff; + + uint32_t y_min = s->offset.y; + uint32_t x_min = s->offset.x; + uint32_t y_max = s->offset.y + s->extent.height - 1; + uint32_t x_max = s->offset.x + s->extent.width - 1; + + /* Do this math using int64_t so overflow gets clamped correctly. */ + if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) { + y_min = clamp_int64((uint64_t) y_min, + cmd_buffer->state.render_area.offset.y, max); + x_min = clamp_int64((uint64_t) x_min, + cmd_buffer->state.render_area.offset.x, max); + y_max = clamp_int64((uint64_t) y_max, 0, + cmd_buffer->state.render_area.offset.y + + cmd_buffer->state.render_area.extent.height - 1); + x_max = clamp_int64((uint64_t) x_max, 0, + cmd_buffer->state.render_area.offset.x + + cmd_buffer->state.render_area.extent.width - 1); + } else if (fb) { + y_min = clamp_int64((uint64_t) y_min, 0, max); + x_min = clamp_int64((uint64_t) x_min, 0, max); + y_max = clamp_int64((uint64_t) y_max, 0, fb->height - 1); + x_max = clamp_int64((uint64_t) x_max, 0, fb->width - 1); + } + + struct GFX7_SCISSOR_RECT scissor = { + .ScissorRectangleYMin = y_min, + .ScissorRectangleXMin = x_min, + .ScissorRectangleYMax = y_max, + .ScissorRectangleXMax = x_max + }; + + if (s->extent.width <= 0 || s->extent.height <= 0) { + GFX7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 8, + &empty_scissor); + } else { + GFX7_SCISSOR_RECT_pack(NULL, scissor_state.map + i * 8, &scissor); + } + } + + anv_batch_emit(&cmd_buffer->batch, + GFX7_3DSTATE_SCISSOR_STATE_POINTERS, ssp) { + ssp.ScissorRectPointer = scissor_state.offset; + } +} #endif -static uint32_t vk_to_intel_index_type(VkIndexType type) +static uint32_t vk_to_gen_index_type(VkIndexType type) { switch (type) { case VK_INDEX_TYPE_UINT8_EXT: @@ -77,16 +166,23 @@ void genX(CmdBindIndexBuffer)( if (GFX_VERx10 == 75) cmd_buffer->state.restart_index = restart_index_for_type(indexType); cmd_buffer->state.gfx.gfx7.index_buffer = buffer; - cmd_buffer->state.gfx.gfx7.index_type = vk_to_intel_index_type(indexType); + cmd_buffer->state.gfx.gfx7.index_type = vk_to_gen_index_type(indexType); cmd_buffer->state.gfx.gfx7.index_offset = offset; } static uint32_t get_depth_format(struct anv_cmd_buffer *cmd_buffer) { - struct anv_cmd_graphics_state *gfx = &cmd_buffer->state.gfx; + const struct anv_render_pass *pass = cmd_buffer->state.pass; + const struct anv_subpass *subpass = cmd_buffer->state.subpass; + + if (!subpass->depth_stencil_attachment) + return D16_UNORM; + + struct anv_render_pass_attachment *att = + &pass->attachments[subpass->depth_stencil_attachment->attachment]; - switch (gfx->depth_att.vk_format) { + switch (att->format) { case VK_FORMAT_D16_UNORM: case VK_FORMAT_D16_UNORM_S8_UINT: return D16_UNORM; @@ -111,42 +207,11 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) struct anv_dynamic_state *d = &cmd_buffer->state.gfx.dynamic; if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | - ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) { - uint32_t topology; - if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) - topology = pipeline->topology; - else - topology = genX(vk_to_intel_primitive_type)[d->primitive_topology]; - - cmd_buffer->state.gfx.primitive_topology = topology; - } - - if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | ANV_CMD_DIRTY_RENDER_TARGETS | ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH | ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS | ANV_CMD_DIRTY_DYNAMIC_CULL_MODE | - ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE | - ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE | - ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) { - /* Take dynamic primitive topology in to account with - * 3DSTATE_SF::MultisampleRasterizationMode - */ - uint32_t ms_rast_mode = 0; - - if (cmd_buffer->state.gfx.pipeline->dynamic_states & - ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY) { - VkPrimitiveTopology primitive_topology = - cmd_buffer->state.gfx.dynamic.primitive_topology; - - VkPolygonMode dynamic_raster_mode = - genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline, - primitive_topology); - - ms_rast_mode = - genX(ms_rasterization_mode)(pipeline, dynamic_raster_mode); - } - + ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE)) { uint32_t sf_dw[GENX(3DSTATE_SF_length)]; struct GENX(3DSTATE_SF) sf = { GENX(3DSTATE_SF_header), @@ -155,12 +220,8 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) .GlobalDepthOffsetConstant = d->depth_bias.bias, .GlobalDepthOffsetScale = d->depth_bias.slope, .GlobalDepthOffsetClamp = d->depth_bias.clamp, - .FrontWinding = genX(vk_to_intel_front_face)[d->front_face], - .CullMode = genX(vk_to_intel_cullmode)[d->cull_mode], - .GlobalDepthOffsetEnableSolid = d->depth_bias_enable, - .GlobalDepthOffsetEnableWireframe = d->depth_bias_enable, - .GlobalDepthOffsetEnablePoint = d->depth_bias_enable, - .MultisampleRasterizationMode = ms_rast_mode, + .FrontWinding = genX(vk_to_gen_front_face)[d->front_face], + .CullMode = genX(vk_to_gen_cullmode)[d->cull_mode], }; GENX(3DSTATE_SF_pack)(NULL, sf_dw, &sf); @@ -221,16 +282,16 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) .DepthTestEnable = d->depth_test_enable, .DepthBufferWriteEnable = d->depth_test_enable && d->depth_write_enable, - .DepthTestFunction = genX(vk_to_intel_compare_op)[d->depth_compare_op], + .DepthTestFunction = genX(vk_to_gen_compare_op)[d->depth_compare_op], .StencilTestEnable = d->stencil_test_enable, - .StencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.fail_op], - .StencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.pass_op], - .StencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.front.depth_fail_op], - .StencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.front.compare_op], - .BackfaceStencilFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.fail_op], - .BackfaceStencilPassDepthPassOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.pass_op], - .BackfaceStencilPassDepthFailOp = genX(vk_to_intel_stencil_op)[d->stencil_op.back.depth_fail_op], - .BackfaceStencilTestFunction = genX(vk_to_intel_compare_op)[d->stencil_op.back.compare_op], + .StencilFailOp = genX(vk_to_gen_stencil_op)[d->stencil_op.front.fail_op], + .StencilPassDepthPassOp = genX(vk_to_gen_stencil_op)[d->stencil_op.front.pass_op], + .StencilPassDepthFailOp = genX(vk_to_gen_stencil_op)[d->stencil_op.front.depth_fail_op], + .StencilTestFunction = genX(vk_to_gen_compare_op)[d->stencil_op.front.compare_op], + .BackfaceStencilFailOp = genX(vk_to_gen_stencil_op)[d->stencil_op.back.fail_op], + .BackfaceStencilPassDepthPassOp = genX(vk_to_gen_stencil_op)[d->stencil_op.back.pass_op], + .BackfaceStencilPassDepthFailOp = genX(vk_to_gen_stencil_op)[d->stencil_op.back.depth_fail_op], + .BackfaceStencilTestFunction = genX(vk_to_gen_compare_op)[d->stencil_op.back.compare_op], }; GENX(DEPTH_STENCIL_STATE_pack)(NULL, depth_stencil_dw, &depth_stencil); @@ -247,21 +308,20 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) if (cmd_buffer->state.gfx.gfx7.index_buffer && cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | - ANV_CMD_DIRTY_INDEX_BUFFER | - ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE)) { + ANV_CMD_DIRTY_INDEX_BUFFER)) { struct anv_buffer *buffer = cmd_buffer->state.gfx.gfx7.index_buffer; uint32_t offset = cmd_buffer->state.gfx.gfx7.index_offset; #if GFX_VERx10 == 75 anv_batch_emit(&cmd_buffer->batch, GFX75_3DSTATE_VF, vf) { - vf.IndexedDrawCutIndexEnable = d->primitive_restart_enable; + vf.IndexedDrawCutIndexEnable = pipeline->primitive_restart; vf.CutIndex = cmd_buffer->state.restart_index; } #endif anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_INDEX_BUFFER), ib) { #if GFX_VERx10 != 75 - ib.CutIndexEnable = d->primitive_restart_enable; + ib.CutIndexEnable = pipeline->primitive_restart; #endif ib.IndexFormat = cmd_buffer->state.gfx.gfx7.index_type; ib.MOCS = anv_mocs(cmd_buffer->device, @@ -274,89 +334,22 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) } } - /* 3DSTATE_WM in the hope we can avoid spawning fragment shaders - * threads or if we have dirty dynamic primitive topology state and - * need to toggle 3DSTATE_WM::MultisampleRasterizationMode dynamically. - */ if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | - ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE | ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY)) { - VkPolygonMode dynamic_raster_mode; - VkPrimitiveTopology primitive_topology = d->primitive_topology; - dynamic_raster_mode = - genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline, - primitive_topology); - - uint32_t dwords[GENX(3DSTATE_WM_length)]; - struct GENX(3DSTATE_WM) wm = { - GENX(3DSTATE_WM_header), - - .ThreadDispatchEnable = anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) && - (pipeline->force_fragment_thread_dispatch || - !anv_cmd_buffer_all_color_write_masked(cmd_buffer)), - .MultisampleRasterizationMode = - genX(ms_rasterization_mode)(pipeline, - dynamic_raster_mode), - }; - GENX(3DSTATE_WM_pack)(NULL, dwords, &wm); + uint32_t topology; + if (anv_pipeline_has_stage(pipeline, MESA_SHADER_TESS_EVAL)) + topology = pipeline->topology; + else + topology = genX(vk_to_gen_primitive_type)[d->primitive_topology]; - anv_batch_emit_merge(&cmd_buffer->batch, dwords, pipeline->gfx7.wm); + cmd_buffer->state.gfx.primitive_topology = topology; } - if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | - ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS)) { + if (cmd_buffer->device->vk.enabled_extensions.EXT_sample_locations && + cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) { genX(emit_multisample)(&cmd_buffer->batch, - pipeline->rasterization_samples, - anv_dynamic_state_get_sample_locations(d, - pipeline->rasterization_samples)); - } - - if (cmd_buffer->state.gfx.dirty & (ANV_CMD_DIRTY_PIPELINE | - ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE | - ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP)) { - const uint8_t color_writes = cmd_buffer->state.gfx.dynamic.color_writes; - - /* Blend states of each RT */ - uint32_t blend_dws[GENX(BLEND_STATE_length) + - MAX_RTS * GENX(BLEND_STATE_ENTRY_length)]; - uint32_t *dws = blend_dws; - memset(blend_dws, 0, sizeof(blend_dws)); - - /* Skip this part */ - dws += GENX(BLEND_STATE_length); - - for (uint32_t i = 0; i < MAX_RTS; i++) { - /* Disable anything above the current number of color attachments. */ - bool write_disabled = i >= cmd_buffer->state.gfx.color_att_count || - (color_writes & BITFIELD_BIT(i)) == 0; - struct GENX(BLEND_STATE_ENTRY) entry = { - .WriteDisableAlpha = write_disabled || - (pipeline->color_comp_writes[i] & - VK_COLOR_COMPONENT_A_BIT) == 0, - .WriteDisableRed = write_disabled || - (pipeline->color_comp_writes[i] & - VK_COLOR_COMPONENT_R_BIT) == 0, - .WriteDisableGreen = write_disabled || - (pipeline->color_comp_writes[i] & - VK_COLOR_COMPONENT_G_BIT) == 0, - .WriteDisableBlue = write_disabled || - (pipeline->color_comp_writes[i] & - VK_COLOR_COMPONENT_B_BIT) == 0, - .LogicOpFunction = genX(vk_to_intel_logic_op)[d->logic_op], - }; - GENX(BLEND_STATE_ENTRY_pack)(NULL, dws, &entry); - dws += GENX(BLEND_STATE_ENTRY_length); - } - - uint32_t num_dwords = GENX(BLEND_STATE_length) + - GENX(BLEND_STATE_ENTRY_length) * MAX_RTS; - - struct anv_state blend_states = - anv_cmd_buffer_merge_dynamic(cmd_buffer, blend_dws, - pipeline->gfx7.blend_state, num_dwords, 64); - anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) { - bsp.BlendStatePointer = blend_states.offset; - } + cmd_buffer->state.gfx.dynamic.sample_locations.samples, + cmd_buffer->state.gfx.dynamic.sample_locations.locations); } cmd_buffer->state.gfx.dirty = 0; |