1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "draw/draw_pipe.h" 29bf215546Sopenharmony_ci#include "util/u_math.h" 30bf215546Sopenharmony_ci#include "util/u_memory.h" 31bf215546Sopenharmony_ci#include "util/u_pack_color.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "i915_batch.h" 34bf215546Sopenharmony_ci#include "i915_context.h" 35bf215546Sopenharmony_ci#include "i915_reg.h" 36bf215546Sopenharmony_ci#include "i915_state.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/** 39bf215546Sopenharmony_ci * Primitive emit to hardware. No support for vertex buffers or any 40bf215546Sopenharmony_ci * nice fast paths. 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_cistruct setup_stage { 43bf215546Sopenharmony_ci struct draw_stage stage; /**< This must be first (base class) */ 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci struct i915_context *i915; 46bf215546Sopenharmony_ci}; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci/** 49bf215546Sopenharmony_ci * Basically a cast wrapper. 50bf215546Sopenharmony_ci */ 51bf215546Sopenharmony_cistatic inline struct setup_stage * 52bf215546Sopenharmony_cisetup_stage(struct draw_stage *stage) 53bf215546Sopenharmony_ci{ 54bf215546Sopenharmony_ci return (struct setup_stage *)stage; 55bf215546Sopenharmony_ci} 56bf215546Sopenharmony_ci 57bf215546Sopenharmony_ci/** 58bf215546Sopenharmony_ci * Extract the needed fields from vertex_header and emit i915 dwords. 59bf215546Sopenharmony_ci * Recall that the vertices are constructed by the 'draw' module and 60bf215546Sopenharmony_ci * have a couple of slots at the beginning (1-dword header, 4-dword 61bf215546Sopenharmony_ci * clip pos) that we ignore here. 62bf215546Sopenharmony_ci */ 63bf215546Sopenharmony_cistatic inline void 64bf215546Sopenharmony_ciemit_hw_vertex(struct i915_context *i915, const struct vertex_header *vertex) 65bf215546Sopenharmony_ci{ 66bf215546Sopenharmony_ci const struct vertex_info *vinfo = &i915->current.vertex_info; 67bf215546Sopenharmony_ci uint32_t i; 68bf215546Sopenharmony_ci uint32_t count = 0; /* for debug/sanity */ 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci assert(!i915->dirty); 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci for (i = 0; i < vinfo->num_attribs; i++) { 73bf215546Sopenharmony_ci const uint32_t j = vinfo->attrib[i].src_index; 74bf215546Sopenharmony_ci const float *attrib = vertex->data[j]; 75bf215546Sopenharmony_ci switch (vinfo->attrib[i].emit) { 76bf215546Sopenharmony_ci case EMIT_1F: 77bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[0])); 78bf215546Sopenharmony_ci count++; 79bf215546Sopenharmony_ci break; 80bf215546Sopenharmony_ci case EMIT_2F: 81bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[0])); 82bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[1])); 83bf215546Sopenharmony_ci count += 2; 84bf215546Sopenharmony_ci break; 85bf215546Sopenharmony_ci case EMIT_3F: 86bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[0])); 87bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[1])); 88bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[2])); 89bf215546Sopenharmony_ci count += 3; 90bf215546Sopenharmony_ci break; 91bf215546Sopenharmony_ci case EMIT_4F: 92bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[0])); 93bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[1])); 94bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[2])); 95bf215546Sopenharmony_ci OUT_BATCH(fui(attrib[3])); 96bf215546Sopenharmony_ci count += 4; 97bf215546Sopenharmony_ci break; 98bf215546Sopenharmony_ci case EMIT_4UB: 99bf215546Sopenharmony_ci OUT_BATCH( 100bf215546Sopenharmony_ci pack_ub4(float_to_ubyte(attrib[0]), float_to_ubyte(attrib[1]), 101bf215546Sopenharmony_ci float_to_ubyte(attrib[2]), float_to_ubyte(attrib[3]))); 102bf215546Sopenharmony_ci count += 1; 103bf215546Sopenharmony_ci break; 104bf215546Sopenharmony_ci case EMIT_4UB_BGRA: 105bf215546Sopenharmony_ci OUT_BATCH( 106bf215546Sopenharmony_ci pack_ub4(float_to_ubyte(attrib[2]), float_to_ubyte(attrib[1]), 107bf215546Sopenharmony_ci float_to_ubyte(attrib[0]), float_to_ubyte(attrib[3]))); 108bf215546Sopenharmony_ci count += 1; 109bf215546Sopenharmony_ci break; 110bf215546Sopenharmony_ci default: 111bf215546Sopenharmony_ci assert(0); 112bf215546Sopenharmony_ci } 113bf215546Sopenharmony_ci } 114bf215546Sopenharmony_ci assert(count == vinfo->size); 115bf215546Sopenharmony_ci} 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_cistatic inline void 118bf215546Sopenharmony_ciemit_prim(struct draw_stage *stage, struct prim_header *prim, unsigned hwprim, 119bf215546Sopenharmony_ci unsigned nr) 120bf215546Sopenharmony_ci{ 121bf215546Sopenharmony_ci struct i915_context *i915 = setup_stage(stage)->i915; 122bf215546Sopenharmony_ci unsigned vertex_size; 123bf215546Sopenharmony_ci unsigned i; 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ci if (i915->dirty) 126bf215546Sopenharmony_ci i915_update_derived(i915); 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci if (i915->hardware_dirty) 129bf215546Sopenharmony_ci i915_emit_hardware_state(i915); 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci /* need to do this after validation! */ 132bf215546Sopenharmony_ci vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ 133bf215546Sopenharmony_ci assert(vertex_size >= 12); /* never smaller than 12 bytes */ 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci if (!BEGIN_BATCH(1 + nr * vertex_size / 4)) { 136bf215546Sopenharmony_ci FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci /* Make sure state is re-emitted after a flush: 139bf215546Sopenharmony_ci */ 140bf215546Sopenharmony_ci i915_emit_hardware_state(i915); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci if (!BEGIN_BATCH(1 + nr * vertex_size / 4)) { 143bf215546Sopenharmony_ci assert(0); 144bf215546Sopenharmony_ci return; 145bf215546Sopenharmony_ci } 146bf215546Sopenharmony_ci } 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci /* Emit each triangle as a single primitive. I told you this was 149bf215546Sopenharmony_ci * simple. 150bf215546Sopenharmony_ci */ 151bf215546Sopenharmony_ci OUT_BATCH(_3DPRIMITIVE | hwprim | ((4 + vertex_size * nr) / 4 - 2)); 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci for (i = 0; i < nr; i++) 154bf215546Sopenharmony_ci emit_hw_vertex(i915, prim->v[i]); 155bf215546Sopenharmony_ci} 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_cistatic void 158bf215546Sopenharmony_cisetup_tri(struct draw_stage *stage, struct prim_header *prim) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci emit_prim(stage, prim, PRIM3D_TRILIST, 3); 161bf215546Sopenharmony_ci} 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_cistatic void 164bf215546Sopenharmony_cisetup_line(struct draw_stage *stage, struct prim_header *prim) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci emit_prim(stage, prim, PRIM3D_LINELIST, 2); 167bf215546Sopenharmony_ci} 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_cistatic void 170bf215546Sopenharmony_cisetup_point(struct draw_stage *stage, struct prim_header *prim) 171bf215546Sopenharmony_ci{ 172bf215546Sopenharmony_ci emit_prim(stage, prim, PRIM3D_POINTLIST, 1); 173bf215546Sopenharmony_ci} 174bf215546Sopenharmony_ci 175bf215546Sopenharmony_cistatic void 176bf215546Sopenharmony_cisetup_flush(struct draw_stage *stage, unsigned flags) 177bf215546Sopenharmony_ci{ 178bf215546Sopenharmony_ci} 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_cistatic void 181bf215546Sopenharmony_cireset_stipple_counter(struct draw_stage *stage) 182bf215546Sopenharmony_ci{ 183bf215546Sopenharmony_ci} 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_cistatic void 186bf215546Sopenharmony_cirender_destroy(struct draw_stage *stage) 187bf215546Sopenharmony_ci{ 188bf215546Sopenharmony_ci FREE(stage); 189bf215546Sopenharmony_ci} 190bf215546Sopenharmony_ci 191bf215546Sopenharmony_ci/** 192bf215546Sopenharmony_ci * Create a new primitive setup/render stage. This gets plugged into 193bf215546Sopenharmony_ci * the 'draw' module's pipeline. 194bf215546Sopenharmony_ci */ 195bf215546Sopenharmony_cistruct draw_stage * 196bf215546Sopenharmony_cii915_draw_render_stage(struct i915_context *i915) 197bf215546Sopenharmony_ci{ 198bf215546Sopenharmony_ci struct setup_stage *setup = CALLOC_STRUCT(setup_stage); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci setup->i915 = i915; 201bf215546Sopenharmony_ci setup->stage.draw = i915->draw; 202bf215546Sopenharmony_ci setup->stage.point = setup_point; 203bf215546Sopenharmony_ci setup->stage.line = setup_line; 204bf215546Sopenharmony_ci setup->stage.tri = setup_tri; 205bf215546Sopenharmony_ci setup->stage.flush = setup_flush; 206bf215546Sopenharmony_ci setup->stage.reset_stipple_counter = reset_stipple_counter; 207bf215546Sopenharmony_ci setup->stage.destroy = render_destroy; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci return &setup->stage; 210bf215546Sopenharmony_ci} 211