Path: blob/21.2-virgl/src/gallium/drivers/i915/i915_prim_emit.c
4570 views
/**************************************************************************1*2* Copyright 2007 VMware, Inc.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 (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627#include "draw/draw_pipe.h"28#include "util/u_math.h"29#include "util/u_memory.h"30#include "util/u_pack_color.h"3132#include "i915_batch.h"33#include "i915_context.h"34#include "i915_reg.h"35#include "i915_state.h"3637/**38* Primitive emit to hardware. No support for vertex buffers or any39* nice fast paths.40*/41struct setup_stage {42struct draw_stage stage; /**< This must be first (base class) */4344struct i915_context *i915;45};4647/**48* Basically a cast wrapper.49*/50static inline struct setup_stage *51setup_stage(struct draw_stage *stage)52{53return (struct setup_stage *)stage;54}5556/**57* Extract the needed fields from vertex_header and emit i915 dwords.58* Recall that the vertices are constructed by the 'draw' module and59* have a couple of slots at the beginning (1-dword header, 4-dword60* clip pos) that we ignore here.61*/62static inline void63emit_hw_vertex(struct i915_context *i915, const struct vertex_header *vertex)64{65const struct vertex_info *vinfo = &i915->current.vertex_info;66uint32_t i;67uint32_t count = 0; /* for debug/sanity */6869assert(!i915->dirty);7071for (i = 0; i < vinfo->num_attribs; i++) {72const uint32_t j = vinfo->attrib[i].src_index;73const float *attrib = vertex->data[j];74switch (vinfo->attrib[i].emit) {75case EMIT_1F:76OUT_BATCH(fui(attrib[0]));77count++;78break;79case EMIT_2F:80OUT_BATCH(fui(attrib[0]));81OUT_BATCH(fui(attrib[1]));82count += 2;83break;84case EMIT_3F:85OUT_BATCH(fui(attrib[0]));86OUT_BATCH(fui(attrib[1]));87OUT_BATCH(fui(attrib[2]));88count += 3;89break;90case EMIT_4F:91OUT_BATCH(fui(attrib[0]));92OUT_BATCH(fui(attrib[1]));93OUT_BATCH(fui(attrib[2]));94OUT_BATCH(fui(attrib[3]));95count += 4;96break;97case EMIT_4UB:98OUT_BATCH(99pack_ub4(float_to_ubyte(attrib[0]), float_to_ubyte(attrib[1]),100float_to_ubyte(attrib[2]), float_to_ubyte(attrib[3])));101count += 1;102break;103case EMIT_4UB_BGRA:104OUT_BATCH(105pack_ub4(float_to_ubyte(attrib[2]), float_to_ubyte(attrib[1]),106float_to_ubyte(attrib[0]), float_to_ubyte(attrib[3])));107count += 1;108break;109default:110assert(0);111}112}113assert(count == vinfo->size);114}115116static inline void117emit_prim(struct draw_stage *stage, struct prim_header *prim, unsigned hwprim,118unsigned nr)119{120struct i915_context *i915 = setup_stage(stage)->i915;121unsigned vertex_size;122unsigned i;123124if (i915->dirty)125i915_update_derived(i915);126127if (i915->hardware_dirty)128i915_emit_hardware_state(i915);129130/* need to do this after validation! */131vertex_size = i915->current.vertex_info.size * 4; /* in bytes */132assert(vertex_size >= 12); /* never smaller than 12 bytes */133134if (!BEGIN_BATCH(1 + nr * vertex_size / 4)) {135FLUSH_BATCH(NULL, I915_FLUSH_ASYNC);136137/* Make sure state is re-emitted after a flush:138*/139i915_emit_hardware_state(i915);140141if (!BEGIN_BATCH(1 + nr * vertex_size / 4)) {142assert(0);143return;144}145}146147/* Emit each triangle as a single primitive. I told you this was148* simple.149*/150OUT_BATCH(_3DPRIMITIVE | hwprim | ((4 + vertex_size * nr) / 4 - 2));151152for (i = 0; i < nr; i++)153emit_hw_vertex(i915, prim->v[i]);154}155156static void157setup_tri(struct draw_stage *stage, struct prim_header *prim)158{159emit_prim(stage, prim, PRIM3D_TRILIST, 3);160}161162static void163setup_line(struct draw_stage *stage, struct prim_header *prim)164{165emit_prim(stage, prim, PRIM3D_LINELIST, 2);166}167168static void169setup_point(struct draw_stage *stage, struct prim_header *prim)170{171emit_prim(stage, prim, PRIM3D_POINTLIST, 1);172}173174static void175setup_flush(struct draw_stage *stage, unsigned flags)176{177}178179static void180reset_stipple_counter(struct draw_stage *stage)181{182}183184static void185render_destroy(struct draw_stage *stage)186{187FREE(stage);188}189190/**191* Create a new primitive setup/render stage. This gets plugged into192* the 'draw' module's pipeline.193*/194struct draw_stage *195i915_draw_render_stage(struct i915_context *i915)196{197struct setup_stage *setup = CALLOC_STRUCT(setup_stage);198199setup->i915 = i915;200setup->stage.draw = i915->draw;201setup->stage.point = setup_point;202setup->stage.line = setup_line;203setup->stage.tri = setup_tri;204setup->stage.flush = setup_flush;205setup->stage.reset_stipple_counter = reset_stipple_counter;206setup->stage.destroy = render_destroy;207208return &setup->stage;209}210211212