2023-11-17 13:49:47 -04:00
|
|
|
/*
|
|
|
|
|
* Copyright 2023 Valve Corporation
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "compiler/nir/nir_builder.h"
|
2025-10-06 12:57:04 +02:00
|
|
|
#include "poly/cl/libpoly.h"
|
2025-11-13 22:05:17 -05:00
|
|
|
#include "poly/nir/poly_nir.h"
|
2025-10-06 12:57:04 +02:00
|
|
|
#include "poly/geometry.h"
|
2023-11-17 13:49:47 -04:00
|
|
|
#include "nir.h"
|
2023-11-18 12:19:04 -04:00
|
|
|
|
|
|
|
|
/*
|
2024-05-09 10:24:23 -04:00
|
|
|
* This file implements basic input assembly in software. It runs on software
|
|
|
|
|
* vertex shaders, as part of geometry/tessellation lowering. It does not apply
|
|
|
|
|
* the topology, which happens in the geometry shader.
|
2023-11-18 12:19:04 -04:00
|
|
|
*/
|
2024-12-01 08:03:13 -05:00
|
|
|
nir_def *
|
2025-10-06 12:57:04 +02:00
|
|
|
poly_nir_load_vertex_id(nir_builder *b, nir_def *id, unsigned index_size_B)
|
2023-11-17 13:49:47 -04:00
|
|
|
{
|
|
|
|
|
/* If drawing with an index buffer, pull the vertex ID. Otherwise, the
|
|
|
|
|
* vertex ID is just the index as-is.
|
|
|
|
|
*/
|
2024-07-17 13:50:35 -04:00
|
|
|
if (index_size_B) {
|
2025-11-13 16:11:20 -05:00
|
|
|
nir_def *p = nir_load_vertex_param_buffer_poly(b);
|
|
|
|
|
id = poly_load_index_buffer(b, p, id, nir_imm_int(b, index_size_B));
|
2023-11-17 13:49:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add the "start", either an index bias or a base vertex. This must happen
|
|
|
|
|
* after indexing for proper index bias behaviour.
|
|
|
|
|
*/
|
|
|
|
|
return nir_iadd(b, id, nir_load_first_vertex(b));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
2024-07-17 13:55:22 -04:00
|
|
|
lower(nir_builder *b, nir_intrinsic_instr *intr, void *data)
|
2023-11-17 13:49:47 -04:00
|
|
|
{
|
2024-07-17 13:50:35 -04:00
|
|
|
unsigned *index_size_B = data;
|
2024-07-17 13:55:22 -04:00
|
|
|
b->cursor = nir_before_instr(&intr->instr);
|
|
|
|
|
|
|
|
|
|
if (intr->intrinsic == nir_intrinsic_load_vertex_id) {
|
2024-12-01 08:03:13 -05:00
|
|
|
nir_def *id = nir_channel(b, nir_load_global_invocation_id(b, 32), 0);
|
2025-10-06 12:57:04 +02:00
|
|
|
nir_def_replace(&intr->def,
|
|
|
|
|
poly_nir_load_vertex_id(b, id, *index_size_B));
|
2024-07-17 13:55:22 -04:00
|
|
|
return true;
|
|
|
|
|
} else if (intr->intrinsic == nir_intrinsic_load_instance_id) {
|
|
|
|
|
nir_def_replace(&intr->def,
|
|
|
|
|
nir_channel(b, nir_load_global_invocation_id(b, 32), 1));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2023-11-17 13:49:47 -04:00
|
|
|
}
|
|
|
|
|
|
2024-01-09 15:50:27 -04:00
|
|
|
bool
|
2025-10-06 12:57:04 +02:00
|
|
|
poly_nir_lower_sw_vs(nir_shader *s, unsigned index_size_B)
|
2023-11-17 13:49:47 -04:00
|
|
|
{
|
2024-07-17 13:55:22 -04:00
|
|
|
return nir_shader_intrinsics_pass(s, lower, nir_metadata_control_flow,
|
|
|
|
|
&index_size_B);
|
2023-11-18 12:19:04 -04:00
|
|
|
}
|