draw: add a mesh primitive assembler.
This is assembles prims from mesh vertex and per-primitive outputs. Reviewed-by: Roland Scheidegger <sroland@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23066>
This commit is contained in:
parent
bb1be13bb8
commit
888fb3d360
4 changed files with 305 additions and 0 deletions
230
src/gallium/auxiliary/draw/draw_mesh_prim.c
Normal file
230
src/gallium/auxiliary/draw/draw_mesh_prim.c
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2023 Red Hat.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Mesh primitive assembler
|
||||
*
|
||||
* This takes vertex and per-primitive data, and assembles a linear set
|
||||
* of draw compatible vertices.
|
||||
*/
|
||||
#include "draw_mesh_prim.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_private.h"
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_prim.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
struct draw_mesh_prim
|
||||
{
|
||||
struct draw_context *draw;
|
||||
|
||||
struct draw_prim_info *output_prims;
|
||||
struct draw_vertex_info *output_verts;
|
||||
|
||||
const struct draw_prim_info *input_prims;
|
||||
const struct draw_vertex_info *input_verts;
|
||||
|
||||
unsigned num_prims;
|
||||
const char *per_prim;
|
||||
uint32_t num_per_prim;
|
||||
uint32_t added_prim_size;
|
||||
int cull_prim_idx;
|
||||
};
|
||||
|
||||
static void
|
||||
add_prim(struct draw_mesh_prim *asmblr, unsigned length)
|
||||
{
|
||||
struct draw_prim_info *output_prims = asmblr->output_prims;
|
||||
|
||||
output_prims->primitive_lengths = realloc(output_prims->primitive_lengths, sizeof(unsigned) * (output_prims->primitive_count + 1));
|
||||
output_prims->primitive_lengths[output_prims->primitive_count] = length;
|
||||
output_prims->primitive_count++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy the vertex header along with its data from the current
|
||||
* vertex buffer into a buffer holding vertices arranged
|
||||
* into decomposed primitives (i.e. buffer without the
|
||||
* adjacency vertices)
|
||||
*/
|
||||
static void
|
||||
copy_verts(struct draw_mesh_prim *asmblr,
|
||||
unsigned *indices, unsigned num_indices)
|
||||
{
|
||||
char *output = (char*)asmblr->output_verts->verts;
|
||||
const char *input = (const char*)asmblr->input_verts->verts;
|
||||
|
||||
for (unsigned i = 0; i < num_indices; ++i) {
|
||||
unsigned idx = indices[i];
|
||||
unsigned output_offset =
|
||||
asmblr->output_verts->count * asmblr->output_verts->stride;
|
||||
unsigned input_offset = asmblr->input_verts->stride * idx;
|
||||
memcpy(output + output_offset, input + input_offset,
|
||||
asmblr->input_verts->vertex_size);
|
||||
|
||||
memcpy(output + output_offset + asmblr->input_verts->vertex_size,
|
||||
asmblr->per_prim + (asmblr->num_prims * asmblr->added_prim_size * 8),
|
||||
asmblr->added_prim_size);
|
||||
asmblr->output_verts->count += 1;
|
||||
}
|
||||
++asmblr->num_prims;
|
||||
}
|
||||
|
||||
static bool
|
||||
cull_prim(struct draw_mesh_prim *asmblr)
|
||||
{
|
||||
if (asmblr->cull_prim_idx == -1)
|
||||
return false;
|
||||
|
||||
const uint32_t *cull_prim_ptr = (uint32_t *)(asmblr->per_prim + (asmblr->num_prims * asmblr->added_prim_size * 8));
|
||||
cull_prim_ptr += (asmblr->cull_prim_idx * 4);
|
||||
|
||||
return (*cull_prim_ptr) ? true : false;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prim_point(struct draw_mesh_prim *asmblr,
|
||||
unsigned idx)
|
||||
{
|
||||
unsigned indices[1];
|
||||
|
||||
indices[0] = idx;
|
||||
|
||||
if (cull_prim(asmblr)) {
|
||||
++asmblr->num_prims;
|
||||
return;
|
||||
}
|
||||
add_prim(asmblr, 1);
|
||||
copy_verts(asmblr, indices, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prim_line(struct draw_mesh_prim *asmblr,
|
||||
unsigned i0, unsigned i1)
|
||||
{
|
||||
unsigned indices[2];
|
||||
|
||||
indices[0] = i0;
|
||||
indices[1] = i1;
|
||||
|
||||
if (cull_prim(asmblr)) {
|
||||
++asmblr->num_prims;
|
||||
return;
|
||||
}
|
||||
add_prim(asmblr, 2);
|
||||
copy_verts(asmblr, indices, 2);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prim_tri(struct draw_mesh_prim *asmblr,
|
||||
unsigned i0, unsigned i1, unsigned i2)
|
||||
{
|
||||
unsigned indices[3];
|
||||
|
||||
indices[0] = i0;
|
||||
indices[1] = i1;
|
||||
indices[2] = i2;
|
||||
|
||||
if (cull_prim(asmblr)) {
|
||||
++asmblr->num_prims;
|
||||
return;
|
||||
}
|
||||
add_prim(asmblr, 3);
|
||||
copy_verts(asmblr, indices, 3);
|
||||
}
|
||||
|
||||
|
||||
#define FUNC assembler_run_linear
|
||||
#define GET_ELT(idx) (start + (idx))
|
||||
#include "draw_mesh_prim_tmp.h"
|
||||
|
||||
#define FUNC assembler_run_elts
|
||||
#define LOCAL_VARS const ushort *elts = input_prims->elts;
|
||||
#define GET_ELT(idx) (elts[start + (idx)])
|
||||
#include "draw_mesh_prim_tmp.h"
|
||||
|
||||
|
||||
void
|
||||
draw_mesh_prim_run(struct draw_context *draw,
|
||||
unsigned num_per_prim_inputs,
|
||||
void *per_prim_inputs,
|
||||
int cull_prim_idx,
|
||||
const struct draw_prim_info *input_prims,
|
||||
const struct draw_vertex_info *input_verts,
|
||||
struct draw_prim_info *output_prims,
|
||||
struct draw_vertex_info *output_verts)
|
||||
{
|
||||
struct draw_mesh_prim asmblr_mesh;
|
||||
struct draw_mesh_prim *asmblr = &asmblr_mesh;
|
||||
unsigned start, i;
|
||||
unsigned max_primitives = input_prims->primitive_count;
|
||||
unsigned max_verts = u_vertices_per_prim(input_prims->prim) * max_primitives;
|
||||
|
||||
asmblr->output_prims = output_prims;
|
||||
asmblr->output_verts = output_verts;
|
||||
asmblr->input_prims = input_prims;
|
||||
asmblr->input_verts = input_verts;
|
||||
asmblr->num_prims = 0;
|
||||
asmblr->num_per_prim = num_per_prim_inputs;
|
||||
asmblr->per_prim = per_prim_inputs;
|
||||
asmblr->cull_prim_idx = cull_prim_idx;
|
||||
|
||||
output_prims->linear = TRUE;
|
||||
output_prims->elts = NULL;
|
||||
output_prims->start = 0;
|
||||
output_prims->prim = input_prims->prim;
|
||||
output_prims->flags = 0x0;
|
||||
output_prims->primitive_lengths = MALLOC(sizeof(unsigned));
|
||||
output_prims->primitive_lengths[0] = 0;
|
||||
output_prims->primitive_count = 0;
|
||||
|
||||
asmblr->added_prim_size = asmblr->num_per_prim * (4 * sizeof(float));
|
||||
output_verts->vertex_size = input_verts->vertex_size + asmblr->added_prim_size;
|
||||
output_verts->stride = output_verts->vertex_size;
|
||||
output_verts->verts = (struct vertex_header*)MALLOC(
|
||||
output_verts->vertex_size * max_verts);
|
||||
output_verts->count = 0;
|
||||
|
||||
for (start = i = 0; i < input_prims->primitive_count;
|
||||
start += input_prims->primitive_lengths[i], i++) {
|
||||
unsigned count = input_prims->primitive_lengths[i];
|
||||
if (input_prims->linear) {
|
||||
assembler_run_linear(asmblr, input_prims, input_verts,
|
||||
start, count);
|
||||
} else {
|
||||
assembler_run_elts(asmblr, input_prims, input_verts,
|
||||
start, count);
|
||||
}
|
||||
}
|
||||
|
||||
output_prims->count = output_verts->count;
|
||||
}
|
||||
42
src/gallium/auxiliary/draw/draw_mesh_prim.h
Normal file
42
src/gallium/auxiliary/draw/draw_mesh_prim.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2023 Red Hat.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef DRAW_MESH_PRIM_H
|
||||
#define DRAW_MESH_PRIM_H
|
||||
|
||||
struct draw_context;
|
||||
struct draw_prim_info;
|
||||
struct draw_vertex_info;
|
||||
|
||||
void
|
||||
draw_mesh_prim_run(struct draw_context *draw,
|
||||
unsigned num_per_prim_inputs,
|
||||
void *per_prim_inputs,
|
||||
int cull_prim_idx,
|
||||
const struct draw_prim_info *in_prim_info,
|
||||
const struct draw_vertex_info *in_vert_info,
|
||||
struct draw_prim_info *out_prim_info,
|
||||
struct draw_vertex_info *out_vert_info);
|
||||
#endif
|
||||
30
src/gallium/auxiliary/draw/draw_mesh_prim_tmp.h
Normal file
30
src/gallium/auxiliary/draw/draw_mesh_prim_tmp.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#define FUNC_VARS \
|
||||
struct draw_mesh_prim *asmblr, \
|
||||
const struct draw_prim_info *input_prims, \
|
||||
const struct draw_vertex_info *input_verts, \
|
||||
unsigned start, \
|
||||
unsigned count
|
||||
|
||||
#define FUNC_ENTER \
|
||||
/* declare more local vars */ \
|
||||
const enum mesa_prim prim = input_prims->prim; \
|
||||
const unsigned prim_flags = input_prims->flags; \
|
||||
const boolean last_vertex_last = false; \
|
||||
switch (prim) { \
|
||||
case MESA_PRIM_POINTS: \
|
||||
case MESA_PRIM_LINES: \
|
||||
case MESA_PRIM_TRIANGLES: \
|
||||
break; \
|
||||
default: \
|
||||
assert(!"unexpected primitive type in prim assembler"); \
|
||||
return; \
|
||||
}
|
||||
|
||||
|
||||
#define POINT(i0) prim_point(asmblr, i0)
|
||||
#define LINE(flags, i0, i1) prim_line(asmblr, i0, i1)
|
||||
#define TRIANGLE(flags, i0, i1, i2) prim_tri(asmblr, i0, i1, i2)
|
||||
#define QUAD(flags, i0, i1, i2, i3)
|
||||
#define PASS_QUADS
|
||||
|
||||
#include "draw_decompose_tmp.h"
|
||||
|
|
@ -36,6 +36,9 @@ files_libgallium = files(
|
|||
'draw/draw_gs_tmp.h',
|
||||
'draw/draw_mesh.c',
|
||||
'draw/draw_mesh.h',
|
||||
'draw/draw_mesh_prim.c',
|
||||
'draw/draw_mesh_prim.h',
|
||||
'draw/draw_mesh_prim_tmp.h',
|
||||
'draw/draw_pipe_aaline.c',
|
||||
'draw/draw_pipe_aapoint.c',
|
||||
'draw/draw_pipe.c',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue