Path: blob/21.2-virgl/src/gallium/auxiliary/tessellator/p_tessellator.cpp
4565 views
/**************************************************************************1*2* Copyright 2020 Red Hat.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the "Software"),7* to deal in the Software without restriction, including without limitation8* the rights to use, copy, modify, merge, publish, distribute, sublicense,9* and/or sell copies of the Software, and to permit persons to whom the10* Software is furnished to do so, subject to the following conditions:11*12* The above copyright notice and this permission notice shall be included13* in all copies or substantial portions of the Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS16* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21* SOFTWARE.22*23**************************************************************************/2425#include "util/u_math.h"26#include "util/u_memory.h"27#include "pipe/p_defines.h"28#include "p_tessellator.h"29#include "tessellator.hpp"3031#include <new>3233namespace pipe_tessellator_wrap34{35/// Wrapper class for the CHWTessellator reference tessellator from MSFT36/// This class will store data not originally stored in CHWTessellator37class pipe_ts : private CHWTessellator38{39private:40typedef CHWTessellator SUPER;41enum pipe_prim_type prim_mode;42PIPE_ALIGN_VAR(32) float domain_points_u[MAX_POINT_COUNT];43PIPE_ALIGN_VAR(32) float domain_points_v[MAX_POINT_COUNT];44uint32_t num_domain_points;4546public:47void Init(enum pipe_prim_type tes_prim_mode,48enum pipe_tess_spacing ts_spacing,49bool tes_vertex_order_cw, bool tes_point_mode)50{51static PIPE_TESSELLATOR_PARTITIONING CVT_TS_D3D_PARTITIONING[] = {52PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD, // PIPE_TESS_SPACING_ODD53PIPE_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN, // PIPE_TESS_SPACING_EVEN54PIPE_TESSELLATOR_PARTITIONING_INTEGER, // PIPE_TESS_SPACING_EQUAL55};5657PIPE_TESSELLATOR_OUTPUT_PRIMITIVE out_prim;58if (tes_point_mode)59out_prim = PIPE_TESSELLATOR_OUTPUT_POINT;60else if (tes_prim_mode == PIPE_PRIM_LINES)61out_prim = PIPE_TESSELLATOR_OUTPUT_LINE;62else if (tes_vertex_order_cw)63out_prim = PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CW;64else65out_prim = PIPE_TESSELLATOR_OUTPUT_TRIANGLE_CCW;6667SUPER::Init(CVT_TS_D3D_PARTITIONING[ts_spacing],68out_prim);6970prim_mode = tes_prim_mode;71num_domain_points = 0;72}7374void Tessellate(const struct pipe_tessellation_factors *tess_factors,75struct pipe_tessellator_data *tess_data)76{77switch (prim_mode)78{79case PIPE_PRIM_QUADS:80SUPER::TessellateQuadDomain(81tess_factors->outer_tf[0],82tess_factors->outer_tf[1],83tess_factors->outer_tf[2],84tess_factors->outer_tf[3],85tess_factors->inner_tf[0],86tess_factors->inner_tf[1]);87break;8889case PIPE_PRIM_TRIANGLES:90SUPER::TessellateTriDomain(91tess_factors->outer_tf[0],92tess_factors->outer_tf[1],93tess_factors->outer_tf[2],94tess_factors->inner_tf[0]);95break;9697case PIPE_PRIM_LINES:98SUPER::TessellateIsoLineDomain(99tess_factors->outer_tf[0],100tess_factors->outer_tf[1]);101break;102103default:104assert(0);105return;106}107108num_domain_points = (uint32_t)SUPER::GetPointCount();109110DOMAIN_POINT *points = SUPER::GetPoints();111for (uint32_t i = 0; i < num_domain_points; i++) {112domain_points_u[i] = points[i].u;113domain_points_v[i] = points[i].v;114}115tess_data->num_domain_points = num_domain_points;116tess_data->domain_points_u = &domain_points_u[0];117tess_data->domain_points_v = &domain_points_v[0];118119tess_data->num_indices = (uint32_t)SUPER::GetIndexCount();120121tess_data->indices = (uint32_t*)SUPER::GetIndices();122}123};124} // namespace Tessellator125126/* allocate tessellator */127struct pipe_tessellator *128p_tess_init(enum pipe_prim_type tes_prim_mode,129enum pipe_tess_spacing spacing,130bool tes_vertex_order_cw, bool tes_point_mode)131{132void *mem;133using pipe_tessellator_wrap::pipe_ts;134135mem = align_malloc(sizeof(pipe_ts), 256);136137pipe_ts* tessellator = new (mem) pipe_ts();138139tessellator->Init(tes_prim_mode, spacing, tes_vertex_order_cw, tes_point_mode);140141return (struct pipe_tessellator *)tessellator;142}143144/* destroy tessellator */145void p_tess_destroy(struct pipe_tessellator *pipe_tess)146{147using pipe_tessellator_wrap::pipe_ts;148pipe_ts *tessellator = (pipe_ts*)pipe_tess;149150tessellator->~pipe_ts();151align_free(tessellator);152}153154/* perform tessellation */155void p_tessellate(struct pipe_tessellator *pipe_tess,156const struct pipe_tessellation_factors *tess_factors,157struct pipe_tessellator_data *tess_data)158{159using pipe_tessellator_wrap::pipe_ts;160pipe_ts *tessellator = (pipe_ts*)pipe_tess;161162tessellator->Tessellate(tess_factors, tess_data);163}164165166167