Path: blob/21.2-virgl/src/gallium/drivers/r300/r300_state_inlines.h
4570 views
/*1* Copyright 2009 Joakim Sindholt <[email protected]>2* Corbin Simpson <[email protected]>3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* on the rights to use, copy, modify, merge, publish, distribute, sub8* license, and/or sell copies of the Software, and to permit persons to whom9* the Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice (including the next12* paragraph) shall be included in all copies or substantial portions of the13* Software.14*15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL18* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,19* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR20* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE21* USE OR OTHER DEALINGS IN THE SOFTWARE. */2223#ifndef R300_STATE_INLINES_H24#define R300_STATE_INLINES_H2526#include "draw/draw_vertex.h"27#include "pipe/p_format.h"28#include "util/format/u_format.h"29#include "r300_reg.h"30#include <stdio.h>3132/* Some maths. These should probably find their way to u_math, if needed. */3334static inline int pack_float_16_6x(float f) {35return ((int)(f * 6.0) & 0xffff);36}3738/* Blend state. */3940static inline uint32_t r300_translate_blend_function(int blend_func,41boolean clamp)42{43switch (blend_func) {44case PIPE_BLEND_ADD:45return clamp ? R300_COMB_FCN_ADD_CLAMP : R300_COMB_FCN_ADD_NOCLAMP;46case PIPE_BLEND_SUBTRACT:47return clamp ? R300_COMB_FCN_SUB_CLAMP : R300_COMB_FCN_SUB_NOCLAMP;48case PIPE_BLEND_REVERSE_SUBTRACT:49return clamp ? R300_COMB_FCN_RSUB_CLAMP : R300_COMB_FCN_RSUB_NOCLAMP;50case PIPE_BLEND_MIN:51return R300_COMB_FCN_MIN;52case PIPE_BLEND_MAX:53return R300_COMB_FCN_MAX;54default:55fprintf(stderr, "r300: Unknown blend function %d\n", blend_func);56assert(0);57break;58}59return 0;60}6162static inline uint32_t r300_translate_blend_factor(int blend_fact)63{64switch (blend_fact) {65case PIPE_BLENDFACTOR_ONE:66return R300_BLEND_GL_ONE;67case PIPE_BLENDFACTOR_SRC_COLOR:68return R300_BLEND_GL_SRC_COLOR;69case PIPE_BLENDFACTOR_SRC_ALPHA:70return R300_BLEND_GL_SRC_ALPHA;71case PIPE_BLENDFACTOR_DST_ALPHA:72return R300_BLEND_GL_DST_ALPHA;73case PIPE_BLENDFACTOR_DST_COLOR:74return R300_BLEND_GL_DST_COLOR;75case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:76return R300_BLEND_GL_SRC_ALPHA_SATURATE;77case PIPE_BLENDFACTOR_CONST_COLOR:78return R300_BLEND_GL_CONST_COLOR;79case PIPE_BLENDFACTOR_CONST_ALPHA:80return R300_BLEND_GL_CONST_ALPHA;81case PIPE_BLENDFACTOR_ZERO:82return R300_BLEND_GL_ZERO;83case PIPE_BLENDFACTOR_INV_SRC_COLOR:84return R300_BLEND_GL_ONE_MINUS_SRC_COLOR;85case PIPE_BLENDFACTOR_INV_SRC_ALPHA:86return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA;87case PIPE_BLENDFACTOR_INV_DST_ALPHA:88return R300_BLEND_GL_ONE_MINUS_DST_ALPHA;89case PIPE_BLENDFACTOR_INV_DST_COLOR:90return R300_BLEND_GL_ONE_MINUS_DST_COLOR;91case PIPE_BLENDFACTOR_INV_CONST_COLOR:92return R300_BLEND_GL_ONE_MINUS_CONST_COLOR;93case PIPE_BLENDFACTOR_INV_CONST_ALPHA:94return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA;9596case PIPE_BLENDFACTOR_SRC1_COLOR:97case PIPE_BLENDFACTOR_SRC1_ALPHA:98case PIPE_BLENDFACTOR_INV_SRC1_COLOR:99case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:100fprintf(stderr, "r300: Implementation error: "101"Bad blend factor %d not supported!\n", blend_fact);102assert(0);103break;104105default:106fprintf(stderr, "r300: Unknown blend factor %d\n", blend_fact);107assert(0);108break;109}110return 0;111}112113/* DSA state. */114115static inline uint32_t r300_translate_depth_stencil_function(int zs_func)116{117switch (zs_func) {118case PIPE_FUNC_NEVER:119return R300_ZS_NEVER;120case PIPE_FUNC_LESS:121return R300_ZS_LESS;122case PIPE_FUNC_EQUAL:123return R300_ZS_EQUAL;124case PIPE_FUNC_LEQUAL:125return R300_ZS_LEQUAL;126case PIPE_FUNC_GREATER:127return R300_ZS_GREATER;128case PIPE_FUNC_NOTEQUAL:129return R300_ZS_NOTEQUAL;130case PIPE_FUNC_GEQUAL:131return R300_ZS_GEQUAL;132case PIPE_FUNC_ALWAYS:133return R300_ZS_ALWAYS;134default:135fprintf(stderr, "r300: Unknown depth/stencil function %d\n",136zs_func);137assert(0);138break;139}140return 0;141}142143static inline uint32_t r300_translate_stencil_op(int s_op)144{145switch (s_op) {146case PIPE_STENCIL_OP_KEEP:147return R300_ZS_KEEP;148case PIPE_STENCIL_OP_ZERO:149return R300_ZS_ZERO;150case PIPE_STENCIL_OP_REPLACE:151return R300_ZS_REPLACE;152case PIPE_STENCIL_OP_INCR:153return R300_ZS_INCR;154case PIPE_STENCIL_OP_DECR:155return R300_ZS_DECR;156case PIPE_STENCIL_OP_INCR_WRAP:157return R300_ZS_INCR_WRAP;158case PIPE_STENCIL_OP_DECR_WRAP:159return R300_ZS_DECR_WRAP;160case PIPE_STENCIL_OP_INVERT:161return R300_ZS_INVERT;162default:163fprintf(stderr, "r300: Unknown stencil op %d", s_op);164assert(0);165break;166}167return 0;168}169170static inline uint32_t r300_translate_alpha_function(int alpha_func)171{172switch (alpha_func) {173case PIPE_FUNC_NEVER:174return R300_FG_ALPHA_FUNC_NEVER;175case PIPE_FUNC_LESS:176return R300_FG_ALPHA_FUNC_LESS;177case PIPE_FUNC_EQUAL:178return R300_FG_ALPHA_FUNC_EQUAL;179case PIPE_FUNC_LEQUAL:180return R300_FG_ALPHA_FUNC_LE;181case PIPE_FUNC_GREATER:182return R300_FG_ALPHA_FUNC_GREATER;183case PIPE_FUNC_NOTEQUAL:184return R300_FG_ALPHA_FUNC_NOTEQUAL;185case PIPE_FUNC_GEQUAL:186return R300_FG_ALPHA_FUNC_GE;187case PIPE_FUNC_ALWAYS:188return R300_FG_ALPHA_FUNC_ALWAYS;189default:190fprintf(stderr, "r300: Unknown alpha function %d", alpha_func);191assert(0);192break;193}194return 0;195}196197static inline uint32_t198r300_translate_polygon_mode_front(unsigned mode) {199switch (mode)200{201case PIPE_POLYGON_MODE_FILL:202return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;203case PIPE_POLYGON_MODE_LINE:204return R300_GA_POLY_MODE_FRONT_PTYPE_LINE;205case PIPE_POLYGON_MODE_POINT:206return R300_GA_POLY_MODE_FRONT_PTYPE_POINT;207208default:209fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,210__FUNCTION__);211return R300_GA_POLY_MODE_FRONT_PTYPE_TRI;212}213}214215static inline uint32_t216r300_translate_polygon_mode_back(unsigned mode) {217switch (mode)218{219case PIPE_POLYGON_MODE_FILL:220return R300_GA_POLY_MODE_BACK_PTYPE_TRI;221case PIPE_POLYGON_MODE_LINE:222return R300_GA_POLY_MODE_BACK_PTYPE_LINE;223case PIPE_POLYGON_MODE_POINT:224return R300_GA_POLY_MODE_BACK_PTYPE_POINT;225226default:227fprintf(stderr, "r300: Bad polygon mode %i in %s\n", mode,228__FUNCTION__);229return R300_GA_POLY_MODE_BACK_PTYPE_TRI;230}231}232233/* Texture sampler state. */234235static inline uint32_t r300_translate_wrap(int wrap)236{237switch (wrap) {238case PIPE_TEX_WRAP_REPEAT:239return R300_TX_REPEAT;240case PIPE_TEX_WRAP_CLAMP:241return R300_TX_CLAMP;242case PIPE_TEX_WRAP_CLAMP_TO_EDGE:243return R300_TX_CLAMP_TO_EDGE;244case PIPE_TEX_WRAP_CLAMP_TO_BORDER:245return R300_TX_CLAMP_TO_BORDER;246case PIPE_TEX_WRAP_MIRROR_REPEAT:247return R300_TX_REPEAT | R300_TX_MIRRORED;248case PIPE_TEX_WRAP_MIRROR_CLAMP:249return R300_TX_CLAMP | R300_TX_MIRRORED;250case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:251return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED;252case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:253return R300_TX_CLAMP_TO_BORDER | R300_TX_MIRRORED;254default:255fprintf(stderr, "r300: Unknown texture wrap %d", wrap);256assert(0);257return 0;258}259}260261static inline uint32_t r300_translate_tex_filters(int min, int mag, int mip,262boolean is_anisotropic)263{264uint32_t retval = 0;265266switch (min) {267case PIPE_TEX_FILTER_NEAREST:268retval |= R300_TX_MIN_FILTER_NEAREST;269break;270case PIPE_TEX_FILTER_LINEAR:271retval |= is_anisotropic ? R300_TX_MIN_FILTER_ANISO :272R300_TX_MIN_FILTER_LINEAR;273break;274default:275fprintf(stderr, "r300: Unknown texture filter %d\n", min);276assert(0);277}278279switch (mag) {280case PIPE_TEX_FILTER_NEAREST:281retval |= R300_TX_MAG_FILTER_NEAREST;282break;283case PIPE_TEX_FILTER_LINEAR:284retval |= is_anisotropic ? R300_TX_MAG_FILTER_ANISO :285R300_TX_MAG_FILTER_LINEAR;286break;287default:288fprintf(stderr, "r300: Unknown texture filter %d\n", mag);289assert(0);290}291292switch (mip) {293case PIPE_TEX_MIPFILTER_NONE:294retval |= R300_TX_MIN_FILTER_MIP_NONE;295break;296case PIPE_TEX_MIPFILTER_NEAREST:297retval |= R300_TX_MIN_FILTER_MIP_NEAREST;298break;299case PIPE_TEX_MIPFILTER_LINEAR:300retval |= R300_TX_MIN_FILTER_MIP_LINEAR;301break;302default:303fprintf(stderr, "r300: Unknown texture filter %d\n", mip);304assert(0);305}306307return retval;308}309310static inline uint32_t r300_anisotropy(unsigned max_aniso)311{312if (max_aniso >= 16) {313return R300_TX_MAX_ANISO_16_TO_1;314} else if (max_aniso >= 8) {315return R300_TX_MAX_ANISO_8_TO_1;316} else if (max_aniso >= 4) {317return R300_TX_MAX_ANISO_4_TO_1;318} else if (max_aniso >= 2) {319return R300_TX_MAX_ANISO_2_TO_1;320} else {321return R300_TX_MAX_ANISO_1_TO_1;322}323}324325static inline uint32_t r500_anisotropy(unsigned max_aniso)326{327if (!max_aniso) {328return 0;329}330max_aniso -= 1;331332// Map the range [0, 15] to [0, 63].333return R500_TX_MAX_ANISO(MIN2((unsigned)(max_aniso*4.2001), 63)) |334R500_TX_ANISO_HIGH_QUALITY;335}336337/* Translate pipe_formats into PSC vertex types. */338static inline uint16_t339r300_translate_vertex_data_type(enum pipe_format format) {340uint32_t result = 0;341const struct util_format_description *desc;342unsigned i;343344if (!format)345format = PIPE_FORMAT_R32_FLOAT;346347desc = util_format_description(format);348349if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {350return R300_INVALID_FORMAT;351}352353/* Find the first non-VOID channel. */354for (i = 0; i < 4; i++) {355if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {356break;357}358}359360switch (desc->channel[i].type) {361/* Half-floats, floats, doubles */362case UTIL_FORMAT_TYPE_FLOAT:363switch (desc->channel[i].size) {364case 16:365/* Supported only on RV350 and later. */366if (desc->nr_channels > 2) {367result = R300_DATA_TYPE_FLT16_4;368} else {369result = R300_DATA_TYPE_FLT16_2;370}371break;372case 32:373result = R300_DATA_TYPE_FLOAT_1 + (desc->nr_channels - 1);374break;375default:376return R300_INVALID_FORMAT;377}378break;379/* Unsigned ints */380case UTIL_FORMAT_TYPE_UNSIGNED:381/* Signed ints */382case UTIL_FORMAT_TYPE_SIGNED:383switch (desc->channel[i].size) {384case 8:385result = R300_DATA_TYPE_BYTE;386break;387case 16:388if (desc->nr_channels > 2) {389result = R300_DATA_TYPE_SHORT_4;390} else {391result = R300_DATA_TYPE_SHORT_2;392}393break;394default:395return R300_INVALID_FORMAT;396}397break;398default:399return R300_INVALID_FORMAT;400}401402if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {403result |= R300_SIGNED;404}405if (desc->channel[i].normalized) {406result |= R300_NORMALIZE;407}408409return result;410}411412static inline uint16_t413r300_translate_vertex_data_swizzle(enum pipe_format format) {414const struct util_format_description *desc;415unsigned i, swizzle = 0;416417if (!format)418return (R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_X_SHIFT) |419(R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Y_SHIFT) |420(R300_SWIZZLE_SELECT_FP_ZERO << R300_SWIZZLE_SELECT_Z_SHIFT) |421(R300_SWIZZLE_SELECT_FP_ONE << R300_SWIZZLE_SELECT_W_SHIFT);422423desc = util_format_description(format);424425if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {426fprintf(stderr, "r300: Bad format %s in %s:%d\n",427util_format_short_name(format), __FUNCTION__, __LINE__);428return 0;429}430431for (i = 0; i < desc->nr_channels; i++) {432swizzle |=433MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);434}435/* Set (0,0,0,1) in unused components. */436for (; i < 3; i++) {437swizzle |= R300_SWIZZLE_SELECT_FP_ZERO << (3*i);438}439for (; i < 4; i++) {440swizzle |= R300_SWIZZLE_SELECT_FP_ONE << (3*i);441}442443return swizzle | (0xf << R300_WRITE_ENA_SHIFT);444}445446#endif /* R300_STATE_INLINES_H */447448449