summaryrefslogtreecommitdiff
path: root/lib/mesa/src
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:13:23 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:13:23 +0000
commitd21826c357bdc90ceabf91f368bd545cbe40c3e9 (patch)
tree2196440b7866e61a44af62a5e459f2a129a33b4d /lib/mesa/src
parent51a0616dc513335458f256ef9b5bf03f4256ad58 (diff)
Import Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src')
-rw-r--r--lib/mesa/src/intel/vulkan/gfx7_cmd_buffer.c257
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;