14a49301eSmrg/**************************************************************************
24a49301eSmrg *
3af69d88dSmrg * Copyright 2007 VMware, Inc.
44a49301eSmrg * All Rights Reserved.
54a49301eSmrg *
64a49301eSmrg * Permission is hereby granted, free of charge, to any person obtaining a
74a49301eSmrg * copy of this software and associated documentation files (the
84a49301eSmrg * "Software"), to deal in the Software without restriction, including
94a49301eSmrg * without limitation the rights to use, copy, modify, merge, publish,
104a49301eSmrg * distribute, sub license, and/or sell copies of the Software, and to
114a49301eSmrg * permit persons to whom the Software is furnished to do so, subject to
124a49301eSmrg * the following conditions:
134a49301eSmrg *
144a49301eSmrg * The above copyright notice and this permission notice (including the
154a49301eSmrg * next paragraph) shall be included in all copies or substantial portions
164a49301eSmrg * of the Software.
174a49301eSmrg *
184a49301eSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
194a49301eSmrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
204a49301eSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21af69d88dSmrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
224a49301eSmrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
234a49301eSmrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
244a49301eSmrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254a49301eSmrg *
264a49301eSmrg **************************************************************************/
274a49301eSmrg
284a49301eSmrg/**
294a49301eSmrg * Post-transform vertex format info.  The vertex_info struct is used by
304a49301eSmrg * the draw_vbuf code to emit hardware-specific vertex layouts into hw
314a49301eSmrg * vertex buffers.
324a49301eSmrg *
334a49301eSmrg * Author:
344a49301eSmrg *    Brian Paul
354a49301eSmrg */
364a49301eSmrg
374a49301eSmrg
384a49301eSmrg#ifndef DRAW_VERTEX_H
394a49301eSmrg#define DRAW_VERTEX_H
404a49301eSmrg
414a49301eSmrg
42cdc920a0Smrg#include "pipe/p_compiler.h"
434a49301eSmrg#include "pipe/p_state.h"
44cdc920a0Smrg#include "util/u_debug.h"
45af69d88dSmrg#include "util/u_memory.h"
464a49301eSmrg
4701e04c3fSmrg#define DRAW_ATTR_NONEXIST 255
484a49301eSmrg
494a49301eSmrg/**
504a49301eSmrg * Vertex attribute emit modes
514a49301eSmrg */
524a49301eSmrgenum attrib_emit {
534a49301eSmrg   EMIT_OMIT,      /**< don't emit the attribute */
544a49301eSmrg   EMIT_1F,
554a49301eSmrg   EMIT_1F_PSIZE,  /**< insert constant point size */
564a49301eSmrg   EMIT_2F,
574a49301eSmrg   EMIT_3F,
584a49301eSmrg   EMIT_4F,
593464ebd5Sriastradh   EMIT_4UB, /**< is RGBA like the rest */
603464ebd5Sriastradh   EMIT_4UB_BGRA
614a49301eSmrg};
624a49301eSmrg
634a49301eSmrg
644a49301eSmrg/**
654a49301eSmrg * Information about hardware/rasterization vertex layout.
664a49301eSmrg */
674a49301eSmrgstruct vertex_info
684a49301eSmrg{
694a49301eSmrg   uint num_attribs;
704a49301eSmrg   uint hwfmt[4];      /**< hardware format info for this format */
714a49301eSmrg   uint size;          /**< total vertex size in dwords */
724a49301eSmrg
734a49301eSmrg   /* Keep this small and at the end of the struct to allow quick
744a49301eSmrg    * memcmp() comparisons.
754a49301eSmrg    */
764a49301eSmrg   struct {
7701e04c3fSmrg      unsigned emit:8;             /**< EMIT_x */
784a49301eSmrg      unsigned src_index:8;          /**< map to post-xform attribs */
79af69d88dSmrg   } attrib[PIPE_MAX_SHADER_OUTPUTS];
804a49301eSmrg};
814a49301eSmrg
8201e04c3fSmrgstatic inline size_t
834a49301eSmrgdraw_vinfo_size( const struct vertex_info *a )
844a49301eSmrg{
854a49301eSmrg   return offsetof(const struct vertex_info, attrib[a->num_attribs]);
864a49301eSmrg}
874a49301eSmrg
8801e04c3fSmrgstatic inline int
894a49301eSmrgdraw_vinfo_compare( const struct vertex_info *a,
904a49301eSmrg                    const struct vertex_info *b )
914a49301eSmrg{
924a49301eSmrg   size_t sizea = draw_vinfo_size( a );
934a49301eSmrg   return memcmp( a, b, sizea );
944a49301eSmrg}
954a49301eSmrg
9601e04c3fSmrgstatic inline void
974a49301eSmrgdraw_vinfo_copy( struct vertex_info *dst,
984a49301eSmrg                 const struct vertex_info *src )
994a49301eSmrg{
1004a49301eSmrg   size_t size = draw_vinfo_size( src );
1014a49301eSmrg   memcpy( dst, src, size );
1024a49301eSmrg}
1034a49301eSmrg
1044a49301eSmrg
1054a49301eSmrg
1064a49301eSmrg/**
1074a49301eSmrg * Add another attribute to the given vertex_info object.
1084a49301eSmrg * \param src_index  indicates which post-transformed vertex attrib slot
1094a49301eSmrg *                   corresponds to this attribute.
1104a49301eSmrg * \return slot in which the attribute was added
1114a49301eSmrg */
11201e04c3fSmrgstatic inline uint
1134a49301eSmrgdraw_emit_vertex_attr(struct vertex_info *vinfo,
1144a49301eSmrg                      enum attrib_emit emit,
115af69d88dSmrg                      int src_index)
1164a49301eSmrg{
1174a49301eSmrg   const uint n = vinfo->num_attribs;
118af69d88dSmrg
119af69d88dSmrg   /* If the src_index is negative, meaning it hasn't been found
12001e04c3fSmrg    * we'll assign it all zeros later - set to DRAW_ATTR_NONEXIST */
121af69d88dSmrg   if (src_index < 0) {
12201e04c3fSmrg      src_index = DRAW_ATTR_NONEXIST;
123af69d88dSmrg   }
124af69d88dSmrg
12501e04c3fSmrg   assert(n < ARRAY_SIZE(vinfo->attrib));
1264a49301eSmrg   vinfo->attrib[n].emit = emit;
1274a49301eSmrg   vinfo->attrib[n].src_index = src_index;
1284a49301eSmrg   vinfo->num_attribs++;
1294a49301eSmrg   return n;
1304a49301eSmrg}
1314a49301eSmrg
1324a49301eSmrg
1334a49301eSmrgextern void draw_compute_vertex_size(struct vertex_info *vinfo);
1344a49301eSmrg
1354a49301eSmrgvoid draw_dump_emitted_vertex(const struct vertex_info *vinfo,
1364a49301eSmrg                              const uint8_t *data);
1374a49301eSmrg
1384a49301eSmrg
13901e04c3fSmrgstatic inline enum pipe_format draw_translate_vinfo_format(enum attrib_emit emit)
1404a49301eSmrg{
1413464ebd5Sriastradh   switch (emit) {
1423464ebd5Sriastradh   case EMIT_OMIT:
1433464ebd5Sriastradh      return PIPE_FORMAT_NONE;
1444a49301eSmrg   case EMIT_1F:
1454a49301eSmrg   case EMIT_1F_PSIZE:
1464a49301eSmrg      return PIPE_FORMAT_R32_FLOAT;
1474a49301eSmrg   case EMIT_2F:
1484a49301eSmrg      return PIPE_FORMAT_R32G32_FLOAT;
1494a49301eSmrg   case EMIT_3F:
1504a49301eSmrg      return PIPE_FORMAT_R32G32B32_FLOAT;
1514a49301eSmrg   case EMIT_4F:
1524a49301eSmrg      return PIPE_FORMAT_R32G32B32A32_FLOAT;
1534a49301eSmrg   case EMIT_4UB:
1544a49301eSmrg      return PIPE_FORMAT_R8G8B8A8_UNORM;
1553464ebd5Sriastradh   case EMIT_4UB_BGRA:
1563464ebd5Sriastradh      return PIPE_FORMAT_B8G8R8A8_UNORM;
1574a49301eSmrg   default:
1583464ebd5Sriastradh      assert(!"unexpected format");
1594a49301eSmrg      return PIPE_FORMAT_NONE;
1604a49301eSmrg   }
1614a49301eSmrg}
1624a49301eSmrg
16301e04c3fSmrgstatic inline unsigned draw_translate_vinfo_size(enum attrib_emit emit)
1643464ebd5Sriastradh{
1653464ebd5Sriastradh   switch (emit) {
1663464ebd5Sriastradh   case EMIT_OMIT:
1673464ebd5Sriastradh      return 0;
1683464ebd5Sriastradh   case EMIT_1F:
1693464ebd5Sriastradh   case EMIT_1F_PSIZE:
1703464ebd5Sriastradh      return 1 * sizeof(float);
1713464ebd5Sriastradh   case EMIT_2F:
1723464ebd5Sriastradh      return 2 * sizeof(float);
1733464ebd5Sriastradh   case EMIT_3F:
1743464ebd5Sriastradh      return 3 * sizeof(float);
1753464ebd5Sriastradh   case EMIT_4F:
1763464ebd5Sriastradh      return 4 * sizeof(float);
1773464ebd5Sriastradh   case EMIT_4UB:
1783464ebd5Sriastradh      return 4 * sizeof(unsigned char);
1793464ebd5Sriastradh   case EMIT_4UB_BGRA:
1803464ebd5Sriastradh      return 4 * sizeof(unsigned char);
1813464ebd5Sriastradh   default:
1823464ebd5Sriastradh      assert(!"unexpected format");
1833464ebd5Sriastradh      return 0;
1843464ebd5Sriastradh   }
1853464ebd5Sriastradh}
1864a49301eSmrg
1874a49301eSmrg#endif /* DRAW_VERTEX_H */
188