1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "util/u_inlines.h" 27bf215546Sopenharmony_ci#include "pipe/p_defines.h" 28bf215546Sopenharmony_ci#include "util/u_math.h" 29bf215546Sopenharmony_ci#include "util/u_memory.h" 30bf215546Sopenharmony_ci#include "util/u_bitmask.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "svga_context.h" 33bf215546Sopenharmony_ci#include "svga_hw_reg.h" 34bf215546Sopenharmony_ci#include "svga_cmd.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic inline unsigned 38bf215546Sopenharmony_cisvga_translate_blend_factor(const struct svga_context *svga, unsigned factor) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci /* Note: there is no SVGA3D_BLENDOP_[INV]BLENDFACTORALPHA so 41bf215546Sopenharmony_ci * we can't translate PIPE_BLENDFACTOR_[INV_]CONST_ALPHA properly. 42bf215546Sopenharmony_ci */ 43bf215546Sopenharmony_ci switch (factor) { 44bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_ZERO: return SVGA3D_BLENDOP_ZERO; 45bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_SRC_ALPHA: return SVGA3D_BLENDOP_SRCALPHA; 46bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_ONE: return SVGA3D_BLENDOP_ONE; 47bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_SRC_COLOR: return SVGA3D_BLENDOP_SRCCOLOR; 48bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_SRC_COLOR: return SVGA3D_BLENDOP_INVSRCCOLOR; 49bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_DST_COLOR: return SVGA3D_BLENDOP_DESTCOLOR; 50bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_DST_COLOR: return SVGA3D_BLENDOP_INVDESTCOLOR; 51bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return SVGA3D_BLENDOP_INVSRCALPHA; 52bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_DST_ALPHA: return SVGA3D_BLENDOP_DESTALPHA; 53bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_DST_ALPHA: return SVGA3D_BLENDOP_INVDESTALPHA; 54bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return SVGA3D_BLENDOP_SRCALPHASAT; 55bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_CONST_COLOR: return SVGA3D_BLENDOP_BLENDFACTOR; 56bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_CONST_COLOR: return SVGA3D_BLENDOP_INVBLENDFACTOR; 57bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_CONST_ALPHA: 58bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) 59bf215546Sopenharmony_ci return SVGA3D_BLENDOP_BLENDFACTORALPHA; 60bf215546Sopenharmony_ci else 61bf215546Sopenharmony_ci return SVGA3D_BLENDOP_BLENDFACTOR; /* as close as we can get */ 62bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_CONST_ALPHA: 63bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) 64bf215546Sopenharmony_ci return SVGA3D_BLENDOP_INVBLENDFACTORALPHA; 65bf215546Sopenharmony_ci else 66bf215546Sopenharmony_ci return SVGA3D_BLENDOP_INVBLENDFACTOR; /* as close as we can get */ 67bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_SRC1_COLOR: return SVGA3D_BLENDOP_SRC1COLOR; 68bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return SVGA3D_BLENDOP_INVSRC1COLOR; 69bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_SRC1_ALPHA: return SVGA3D_BLENDOP_SRC1ALPHA; 70bf215546Sopenharmony_ci case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return SVGA3D_BLENDOP_INVSRC1ALPHA; 71bf215546Sopenharmony_ci case 0: return SVGA3D_BLENDOP_ONE; 72bf215546Sopenharmony_ci default: 73bf215546Sopenharmony_ci assert(0); 74bf215546Sopenharmony_ci return SVGA3D_BLENDOP_ZERO; 75bf215546Sopenharmony_ci } 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic inline unsigned 79bf215546Sopenharmony_cisvga_translate_blend_func(unsigned mode) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci switch (mode) { 82bf215546Sopenharmony_ci case PIPE_BLEND_ADD: return SVGA3D_BLENDEQ_ADD; 83bf215546Sopenharmony_ci case PIPE_BLEND_SUBTRACT: return SVGA3D_BLENDEQ_SUBTRACT; 84bf215546Sopenharmony_ci case PIPE_BLEND_REVERSE_SUBTRACT: return SVGA3D_BLENDEQ_REVSUBTRACT; 85bf215546Sopenharmony_ci case PIPE_BLEND_MIN: return SVGA3D_BLENDEQ_MINIMUM; 86bf215546Sopenharmony_ci case PIPE_BLEND_MAX: return SVGA3D_BLENDEQ_MAXIMUM; 87bf215546Sopenharmony_ci default: 88bf215546Sopenharmony_ci assert(0); 89bf215546Sopenharmony_ci return SVGA3D_BLENDEQ_ADD; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci/** 95bf215546Sopenharmony_ci * Translate gallium logicop mode to SVGA3D logicop mode. 96bf215546Sopenharmony_ci */ 97bf215546Sopenharmony_cistatic int 98bf215546Sopenharmony_citranslate_logicop(enum pipe_logicop op) 99bf215546Sopenharmony_ci{ 100bf215546Sopenharmony_ci switch (op) { 101bf215546Sopenharmony_ci case PIPE_LOGICOP_CLEAR: 102bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_CLEAR; 103bf215546Sopenharmony_ci case PIPE_LOGICOP_NOR: 104bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_NOR; 105bf215546Sopenharmony_ci case PIPE_LOGICOP_AND_INVERTED: 106bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_AND_INVERTED; 107bf215546Sopenharmony_ci case PIPE_LOGICOP_COPY_INVERTED: 108bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_COPY_INVERTED; 109bf215546Sopenharmony_ci case PIPE_LOGICOP_AND_REVERSE: 110bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_AND_REVERSE; 111bf215546Sopenharmony_ci case PIPE_LOGICOP_INVERT: 112bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_INVERT; 113bf215546Sopenharmony_ci case PIPE_LOGICOP_XOR: 114bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_XOR; 115bf215546Sopenharmony_ci case PIPE_LOGICOP_NAND: 116bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_NAND; 117bf215546Sopenharmony_ci case PIPE_LOGICOP_AND: 118bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_AND; 119bf215546Sopenharmony_ci case PIPE_LOGICOP_EQUIV: 120bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_EQUIV; 121bf215546Sopenharmony_ci case PIPE_LOGICOP_NOOP: 122bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_NOOP; 123bf215546Sopenharmony_ci case PIPE_LOGICOP_OR_INVERTED: 124bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_OR_INVERTED; 125bf215546Sopenharmony_ci case PIPE_LOGICOP_COPY: 126bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_COPY; 127bf215546Sopenharmony_ci case PIPE_LOGICOP_OR_REVERSE: 128bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_OR_REVERSE; 129bf215546Sopenharmony_ci case PIPE_LOGICOP_OR: 130bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_OR; 131bf215546Sopenharmony_ci case PIPE_LOGICOP_SET: 132bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_SET; 133bf215546Sopenharmony_ci default: 134bf215546Sopenharmony_ci return SVGA3D_DX11_LOGICOP_COPY; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci}; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci/** 140bf215546Sopenharmony_ci * Define a vgpu10 blend state object for the given 141bf215546Sopenharmony_ci * svga blend state. 142bf215546Sopenharmony_ci */ 143bf215546Sopenharmony_cistatic void 144bf215546Sopenharmony_cidefine_blend_state_object(struct svga_context *svga, 145bf215546Sopenharmony_ci struct svga_blend_state *bs) 146bf215546Sopenharmony_ci{ 147bf215546Sopenharmony_ci SVGA3dDXBlendStatePerRT perRT[SVGA3D_MAX_RENDER_TARGETS]; 148bf215546Sopenharmony_ci int i; 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci assert(svga_have_vgpu10(svga)); 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci bs->id = util_bitmask_add(svga->blend_object_id_bm); 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ci for (i = 0; i < SVGA3D_DX_MAX_RENDER_TARGETS; i++) { 155bf215546Sopenharmony_ci perRT[i].blendEnable = bs->rt[i].blend_enable; 156bf215546Sopenharmony_ci perRT[i].srcBlend = bs->rt[i].srcblend; 157bf215546Sopenharmony_ci perRT[i].destBlend = bs->rt[i].dstblend; 158bf215546Sopenharmony_ci perRT[i].blendOp = bs->rt[i].blendeq; 159bf215546Sopenharmony_ci perRT[i].srcBlendAlpha = bs->rt[i].srcblend_alpha; 160bf215546Sopenharmony_ci perRT[i].destBlendAlpha = bs->rt[i].dstblend_alpha; 161bf215546Sopenharmony_ci perRT[i].blendOpAlpha = bs->rt[i].blendeq_alpha; 162bf215546Sopenharmony_ci perRT[i].renderTargetWriteMask = bs->rt[i].writemask; 163bf215546Sopenharmony_ci perRT[i].logicOpEnable = bs->logicop_enabled; 164bf215546Sopenharmony_ci perRT[i].logicOp = bs->logicop_mode; 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_DefineBlendState(svga->swc, 168bf215546Sopenharmony_ci bs->id, 169bf215546Sopenharmony_ci bs->alpha_to_coverage, 170bf215546Sopenharmony_ci bs->independent_blend_enable, 171bf215546Sopenharmony_ci perRT)); 172bf215546Sopenharmony_ci} 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_ci/** 176bf215546Sopenharmony_ci * If SVGA3D_DEVCAP_LOGIC_BLENDOPS is false, we can't directly implement 177bf215546Sopenharmony_ci * GL's logicops. But we can emulate some of them. We set up the blending 178bf215546Sopenharmony_ci * state for that here. 179bf215546Sopenharmony_ci */ 180bf215546Sopenharmony_cistatic void 181bf215546Sopenharmony_ciemulate_logicop(struct svga_context *svga, 182bf215546Sopenharmony_ci unsigned logicop_func, 183bf215546Sopenharmony_ci struct svga_blend_state *blend, 184bf215546Sopenharmony_ci unsigned buffer) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci switch (logicop_func) { 187bf215546Sopenharmony_ci case PIPE_LOGICOP_XOR: 188bf215546Sopenharmony_ci case PIPE_LOGICOP_INVERT: 189bf215546Sopenharmony_ci blend->need_white_fragments = TRUE; 190bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 191bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ONE; 192bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ONE; 193bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_SUBTRACT; 194bf215546Sopenharmony_ci break; 195bf215546Sopenharmony_ci case PIPE_LOGICOP_CLEAR: 196bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 197bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ZERO; 198bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ZERO; 199bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MINIMUM; 200bf215546Sopenharmony_ci break; 201bf215546Sopenharmony_ci case PIPE_LOGICOP_COPY: 202bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = FALSE; 203bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ONE; 204bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ZERO; 205bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_ADD; 206bf215546Sopenharmony_ci break; 207bf215546Sopenharmony_ci case PIPE_LOGICOP_COPY_INVERTED: 208bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 209bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 210bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ZERO; 211bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_ADD; 212bf215546Sopenharmony_ci break; 213bf215546Sopenharmony_ci case PIPE_LOGICOP_NOOP: 214bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 215bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ZERO; 216bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 217bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_ADD; 218bf215546Sopenharmony_ci break; 219bf215546Sopenharmony_ci case PIPE_LOGICOP_SET: 220bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 221bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ONE; 222bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ONE; 223bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 224bf215546Sopenharmony_ci break; 225bf215546Sopenharmony_ci case PIPE_LOGICOP_AND: 226bf215546Sopenharmony_ci /* Approximate with minimum - works for the 0 & anything case: */ 227bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 228bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 229bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 230bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MINIMUM; 231bf215546Sopenharmony_ci break; 232bf215546Sopenharmony_ci case PIPE_LOGICOP_AND_REVERSE: 233bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 234bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 235bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; 236bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MINIMUM; 237bf215546Sopenharmony_ci break; 238bf215546Sopenharmony_ci case PIPE_LOGICOP_AND_INVERTED: 239bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 240bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 241bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 242bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MINIMUM; 243bf215546Sopenharmony_ci break; 244bf215546Sopenharmony_ci case PIPE_LOGICOP_OR: 245bf215546Sopenharmony_ci /* Approximate with maximum - works for the 1 | anything case: */ 246bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 247bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 248bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 249bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 250bf215546Sopenharmony_ci break; 251bf215546Sopenharmony_ci case PIPE_LOGICOP_OR_REVERSE: 252bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 253bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_SRCCOLOR; 254bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_INVDESTCOLOR; 255bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 256bf215546Sopenharmony_ci break; 257bf215546Sopenharmony_ci case PIPE_LOGICOP_OR_INVERTED: 258bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = TRUE; 259bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR; 260bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_DESTCOLOR; 261bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_MAXIMUM; 262bf215546Sopenharmony_ci break; 263bf215546Sopenharmony_ci case PIPE_LOGICOP_NAND: 264bf215546Sopenharmony_ci case PIPE_LOGICOP_NOR: 265bf215546Sopenharmony_ci case PIPE_LOGICOP_EQUIV: 266bf215546Sopenharmony_ci /* Fill these in with plausible values */ 267bf215546Sopenharmony_ci blend->rt[buffer].blend_enable = FALSE; 268bf215546Sopenharmony_ci blend->rt[buffer].srcblend = SVGA3D_BLENDOP_ONE; 269bf215546Sopenharmony_ci blend->rt[buffer].dstblend = SVGA3D_BLENDOP_ZERO; 270bf215546Sopenharmony_ci blend->rt[buffer].blendeq = SVGA3D_BLENDEQ_ADD; 271bf215546Sopenharmony_ci break; 272bf215546Sopenharmony_ci default: 273bf215546Sopenharmony_ci assert(0); 274bf215546Sopenharmony_ci break; 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci blend->rt[buffer].srcblend_alpha = blend->rt[buffer].srcblend; 277bf215546Sopenharmony_ci blend->rt[buffer].dstblend_alpha = blend->rt[buffer].dstblend; 278bf215546Sopenharmony_ci blend->rt[buffer].blendeq_alpha = blend->rt[buffer].blendeq; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci if (logicop_func == PIPE_LOGICOP_XOR) { 281bf215546Sopenharmony_ci util_debug_message(&svga->debug.callback, CONFORMANCE, 282bf215546Sopenharmony_ci "XOR logicop mode has limited support"); 283bf215546Sopenharmony_ci } 284bf215546Sopenharmony_ci else if (logicop_func != PIPE_LOGICOP_COPY) { 285bf215546Sopenharmony_ci util_debug_message(&svga->debug.callback, CONFORMANCE, 286bf215546Sopenharmony_ci "general logicops are not supported"); 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci} 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_cistatic void * 293bf215546Sopenharmony_cisvga_create_blend_state(struct pipe_context *pipe, 294bf215546Sopenharmony_ci const struct pipe_blend_state *templ) 295bf215546Sopenharmony_ci{ 296bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 297bf215546Sopenharmony_ci struct svga_screen *ss = svga_screen(pipe->screen); 298bf215546Sopenharmony_ci struct svga_blend_state *blend = CALLOC_STRUCT( svga_blend_state ); 299bf215546Sopenharmony_ci unsigned i; 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci if (!blend) 302bf215546Sopenharmony_ci return NULL; 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci /* Find index of first target with blending enabled. If no blending is 305bf215546Sopenharmony_ci * enabled at all, first_enabled will be zero. 306bf215546Sopenharmony_ci */ 307bf215546Sopenharmony_ci unsigned first_enabled = 0; 308bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 309bf215546Sopenharmony_ci if (templ->rt[i].blend_enable) { 310bf215546Sopenharmony_ci first_enabled = i; 311bf215546Sopenharmony_ci break; 312bf215546Sopenharmony_ci } 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci /* Fill in the per-rendertarget blend state. We currently only 316bf215546Sopenharmony_ci * support independent blend enable and colormask per render target. 317bf215546Sopenharmony_ci */ 318bf215546Sopenharmony_ci for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { 319bf215546Sopenharmony_ci /* No way to set this in SVGA3D, and no way to correctly implement it on 320bf215546Sopenharmony_ci * top of D3D9 API. Instead we try to simulate with various blend modes. 321bf215546Sopenharmony_ci */ 322bf215546Sopenharmony_ci if (templ->logicop_enable) { 323bf215546Sopenharmony_ci if (ss->haveBlendLogicops) { 324bf215546Sopenharmony_ci blend->logicop_enabled = TRUE; 325bf215546Sopenharmony_ci blend->logicop_mode = translate_logicop(templ->logicop_func); 326bf215546Sopenharmony_ci blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; 327bf215546Sopenharmony_ci blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD; 328bf215546Sopenharmony_ci blend->rt[i].srcblend = SVGA3D_BLENDOP_ZERO; 329bf215546Sopenharmony_ci blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; 330bf215546Sopenharmony_ci blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ZERO; 331bf215546Sopenharmony_ci blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci else { 334bf215546Sopenharmony_ci emulate_logicop(svga, templ->logicop_func, blend, i); 335bf215546Sopenharmony_ci } 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci else { 338bf215546Sopenharmony_ci /* Note: per-target blend terms are only supported for sm4_1 339bf215546Sopenharmony_ci * device. For vgpu10 device, the blending terms must be identical 340bf215546Sopenharmony_ci * for all targets (this is why we need the first_enabled index). 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_ci const unsigned j = 343bf215546Sopenharmony_ci svga_have_sm4_1(svga) && templ->independent_blend_enable 344bf215546Sopenharmony_ci ? i : first_enabled; 345bf215546Sopenharmony_ci if (templ->independent_blend_enable || templ->rt[j].blend_enable) { 346bf215546Sopenharmony_ci blend->rt[i].srcblend = 347bf215546Sopenharmony_ci svga_translate_blend_factor(svga, templ->rt[j].rgb_src_factor); 348bf215546Sopenharmony_ci blend->rt[i].dstblend = 349bf215546Sopenharmony_ci svga_translate_blend_factor(svga, templ->rt[j].rgb_dst_factor); 350bf215546Sopenharmony_ci blend->rt[i].blendeq = 351bf215546Sopenharmony_ci svga_translate_blend_func(templ->rt[j].rgb_func); 352bf215546Sopenharmony_ci blend->rt[i].srcblend_alpha = 353bf215546Sopenharmony_ci svga_translate_blend_factor(svga, templ->rt[j].alpha_src_factor); 354bf215546Sopenharmony_ci blend->rt[i].dstblend_alpha = 355bf215546Sopenharmony_ci svga_translate_blend_factor(svga, templ->rt[j].alpha_dst_factor); 356bf215546Sopenharmony_ci blend->rt[i].blendeq_alpha = 357bf215546Sopenharmony_ci svga_translate_blend_func(templ->rt[j].alpha_func); 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci if (blend->rt[i].srcblend_alpha != blend->rt[i].srcblend || 360bf215546Sopenharmony_ci blend->rt[i].dstblend_alpha != blend->rt[i].dstblend || 361bf215546Sopenharmony_ci blend->rt[i].blendeq_alpha != blend->rt[i].blendeq) { 362bf215546Sopenharmony_ci blend->rt[i].separate_alpha_blend_enable = TRUE; 363bf215546Sopenharmony_ci } 364bf215546Sopenharmony_ci } 365bf215546Sopenharmony_ci else { 366bf215546Sopenharmony_ci /* disabled - default blend terms */ 367bf215546Sopenharmony_ci blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE; 368bf215546Sopenharmony_ci blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO; 369bf215546Sopenharmony_ci blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD; 370bf215546Sopenharmony_ci blend->rt[i].srcblend_alpha = SVGA3D_BLENDOP_ONE; 371bf215546Sopenharmony_ci blend->rt[i].dstblend_alpha = SVGA3D_BLENDOP_ZERO; 372bf215546Sopenharmony_ci blend->rt[i].blendeq_alpha = SVGA3D_BLENDEQ_ADD; 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci if (templ->independent_blend_enable) { 376bf215546Sopenharmony_ci blend->rt[i].blend_enable = templ->rt[i].blend_enable; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci else { 379bf215546Sopenharmony_ci blend->rt[i].blend_enable = templ->rt[0].blend_enable; 380bf215546Sopenharmony_ci } 381bf215546Sopenharmony_ci } 382bf215546Sopenharmony_ci 383bf215546Sopenharmony_ci /* Some GL blend modes are not supported by the VGPU9 device (there's 384bf215546Sopenharmony_ci * no equivalent of PIPE_BLENDFACTOR_[INV_]CONST_ALPHA). 385bf215546Sopenharmony_ci * When we set this flag, we copy the constant blend alpha value 386bf215546Sopenharmony_ci * to the R, G, B components. 387bf215546Sopenharmony_ci * This works as long as the src/dst RGB blend factors doesn't use 388bf215546Sopenharmony_ci * PIPE_BLENDFACTOR_CONST_COLOR and PIPE_BLENDFACTOR_CONST_ALPHA 389bf215546Sopenharmony_ci * at the same time. There's no work-around for that. 390bf215546Sopenharmony_ci */ 391bf215546Sopenharmony_ci if (!svga_have_vgpu10(svga)) { 392bf215546Sopenharmony_ci if (templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_CONST_ALPHA || 393bf215546Sopenharmony_ci templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_CONST_ALPHA || 394bf215546Sopenharmony_ci templ->rt[0].rgb_src_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA || 395bf215546Sopenharmony_ci templ->rt[0].rgb_dst_factor == PIPE_BLENDFACTOR_INV_CONST_ALPHA) { 396bf215546Sopenharmony_ci blend->blend_color_alpha = TRUE; 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci if (templ->independent_blend_enable) { 401bf215546Sopenharmony_ci blend->rt[i].writemask = templ->rt[i].colormask; 402bf215546Sopenharmony_ci } 403bf215546Sopenharmony_ci else { 404bf215546Sopenharmony_ci blend->rt[i].writemask = templ->rt[0].colormask; 405bf215546Sopenharmony_ci } 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci blend->independent_blend_enable = templ->independent_blend_enable; 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci blend->alpha_to_coverage = templ->alpha_to_coverage; 411bf215546Sopenharmony_ci blend->alpha_to_one = templ->alpha_to_one; 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 414bf215546Sopenharmony_ci define_blend_state_object(svga, blend); 415bf215546Sopenharmony_ci } 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci svga->hud.num_blend_objects++; 418bf215546Sopenharmony_ci SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, 419bf215546Sopenharmony_ci SVGA_STATS_COUNT_BLENDSTATE); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci return blend; 422bf215546Sopenharmony_ci} 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_cistatic void svga_bind_blend_state(struct pipe_context *pipe, 426bf215546Sopenharmony_ci void *blend) 427bf215546Sopenharmony_ci{ 428bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci svga->curr.blend = (struct svga_blend_state*)blend; 431bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_BLEND; 432bf215546Sopenharmony_ci} 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_cistatic void svga_delete_blend_state(struct pipe_context *pipe, 435bf215546Sopenharmony_ci void *blend) 436bf215546Sopenharmony_ci{ 437bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 438bf215546Sopenharmony_ci struct svga_blend_state *bs = 439bf215546Sopenharmony_ci (struct svga_blend_state *) blend; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci if (svga_have_vgpu10(svga) && bs->id != SVGA3D_INVALID_ID) { 442bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyBlendState(svga->swc, bs->id)); 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci if (bs->id == svga->state.hw_draw.blend_id) 445bf215546Sopenharmony_ci svga->state.hw_draw.blend_id = SVGA3D_INVALID_ID; 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_ci util_bitmask_clear(svga->blend_object_id_bm, bs->id); 448bf215546Sopenharmony_ci bs->id = SVGA3D_INVALID_ID; 449bf215546Sopenharmony_ci } 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci FREE(blend); 452bf215546Sopenharmony_ci svga->hud.num_blend_objects--; 453bf215546Sopenharmony_ci} 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_cistatic void svga_set_blend_color( struct pipe_context *pipe, 456bf215546Sopenharmony_ci const struct pipe_blend_color *blend_color ) 457bf215546Sopenharmony_ci{ 458bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci svga->curr.blend_color = *blend_color; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_BLEND_COLOR; 463bf215546Sopenharmony_ci} 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_civoid svga_init_blend_functions( struct svga_context *svga ) 467bf215546Sopenharmony_ci{ 468bf215546Sopenharmony_ci svga->pipe.create_blend_state = svga_create_blend_state; 469bf215546Sopenharmony_ci svga->pipe.bind_blend_state = svga_bind_blend_state; 470bf215546Sopenharmony_ci svga->pipe.delete_blend_state = svga_delete_blend_state; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci svga->pipe.set_blend_color = svga_set_blend_color; 473bf215546Sopenharmony_ci} 474