2007-07-09 16:12:13 -06:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
|
|
|
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sub license, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the
|
|
|
|
* next paragraph) shall be included in all copies or substantial portions
|
|
|
|
* of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
|
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
|
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Authors:
|
|
|
|
* Keith Whitwell <keith@tungstengraphics.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-08-24 17:48:55 -06:00
|
|
|
#include "util/u_memory.h"
|
|
|
|
#include "util/u_math.h"
|
2007-07-09 16:12:13 -06:00
|
|
|
#include "draw_context.h"
|
2008-04-17 14:20:00 +01:00
|
|
|
#include "draw_vs.h"
|
2009-12-14 17:11:46 -05:00
|
|
|
#include "draw_gs.h"
|
2007-07-09 16:12:13 -06:00
|
|
|
|
2007-08-20 16:43:58 -06:00
|
|
|
|
2007-07-09 16:12:13 -06:00
|
|
|
struct draw_context *draw_create( void )
|
|
|
|
{
|
|
|
|
struct draw_context *draw = CALLOC_STRUCT( draw_context );
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
if (draw == NULL)
|
|
|
|
goto fail;
|
2007-07-09 16:12:13 -06:00
|
|
|
|
2010-02-22 22:02:58 -05:00
|
|
|
if (!draw_init(draw))
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
return draw;
|
|
|
|
|
|
|
|
fail:
|
|
|
|
draw_destroy( draw );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean draw_init(struct draw_context *draw)
|
|
|
|
{
|
2007-07-09 16:12:13 -06:00
|
|
|
ASSIGN_4V( draw->plane[0], -1, 0, 0, 1 );
|
|
|
|
ASSIGN_4V( draw->plane[1], 1, 0, 0, 1 );
|
|
|
|
ASSIGN_4V( draw->plane[2], 0, -1, 0, 1 );
|
|
|
|
ASSIGN_4V( draw->plane[3], 0, 1, 0, 1 );
|
|
|
|
ASSIGN_4V( draw->plane[4], 0, 0, 1, 1 ); /* yes these are correct */
|
|
|
|
ASSIGN_4V( draw->plane[5], 0, 0, -1, 1 ); /* mesa's a bit wonky */
|
|
|
|
draw->nr_planes = 6;
|
|
|
|
|
2008-01-22 10:16:30 -07:00
|
|
|
|
2008-01-25 17:21:05 -07:00
|
|
|
draw->reduced_prim = ~0; /* != any of PIPE_PRIM_x */
|
2007-10-11 11:09:36 -06:00
|
|
|
|
2008-04-17 23:44:32 +01:00
|
|
|
|
2008-04-19 15:29:27 +01:00
|
|
|
if (!draw_pipeline_init( draw ))
|
2010-02-22 22:02:58 -05:00
|
|
|
return FALSE;
|
2008-04-17 23:44:32 +01:00
|
|
|
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
if (!draw_pt_init( draw ))
|
2010-02-22 22:02:58 -05:00
|
|
|
return FALSE;
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
|
2008-05-13 13:40:22 +01:00
|
|
|
if (!draw_vs_init( draw ))
|
2010-02-22 22:02:58 -05:00
|
|
|
return FALSE;
|
2008-05-13 13:40:22 +01:00
|
|
|
|
2009-12-14 17:11:46 -05:00
|
|
|
if (!draw_gs_init( draw ))
|
2010-02-22 22:02:58 -05:00
|
|
|
return FALSE;
|
2009-12-14 17:11:46 -05:00
|
|
|
|
2010-02-22 22:02:58 -05:00
|
|
|
return TRUE;
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void draw_destroy( struct draw_context *draw )
|
|
|
|
{
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
if (!draw)
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
2008-04-17 23:44:32 +01:00
|
|
|
|
2008-03-11 14:23:08 +00:00
|
|
|
/* Not so fast -- we're just borrowing this at the moment.
|
|
|
|
*
|
2008-03-10 19:49:15 +00:00
|
|
|
if (draw->render)
|
|
|
|
draw->render->destroy( draw->render );
|
2008-03-11 14:23:08 +00:00
|
|
|
*/
|
2008-03-10 19:49:15 +00:00
|
|
|
|
2008-04-19 15:29:27 +01:00
|
|
|
draw_pipeline_destroy( draw );
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
draw_pt_destroy( draw );
|
2008-05-13 13:40:22 +01:00
|
|
|
draw_vs_destroy( draw );
|
2010-01-16 09:30:28 +00:00
|
|
|
draw_gs_destroy( draw );
|
gallium: beginnings of draw module vertex rework
Trying to put a structure in place that we can actually optimize.
Initially just implementing a passthrough mode, this will fairly soon
replace all the vertex_cache/prim_queue/shader_queue stuff that's so
hard to understand...
Split the vertex processing into a couple of distinct stages:
- Frontend
- Prepares two lists of elements (fetch and draw) to be processed
by the next stage. This stage doesn't fetch or draw vertices, but
makes the decision which to draw. Multiple implementations of this
will implement different strategies, currently just a vcache
implementation.
- MiddleEnd
- Takes the list of fetch elements, fetches them, runs the vertex
shader, cliptest, viewport transform on them to produce a
linear array of vertex_header vertices.
- Passes that list of vertices, plus the draw_elements (which index
into that list) onto the backend
- Backend
- Either the existing primitive/clipping pipeline, or the vbuf_render
hardware backend provided by the driver.
Currently, the middle-end is the old passthrough code, and it build hardware
vertices, not vertex_header vertices as above. It may be that passthrough
is a special case in this respect.
2008-03-23 16:44:59 +00:00
|
|
|
|
2007-10-29 16:20:45 +00:00
|
|
|
FREE( draw );
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-06 17:07:09 -06:00
|
|
|
|
2007-09-26 11:56:17 +01:00
|
|
|
void draw_flush( struct draw_context *draw )
|
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_BACKEND );
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-10 18:02:27 -07:00
|
|
|
/**
|
|
|
|
* Specify the Minimum Resolvable Depth factor for polygon offset.
|
|
|
|
* This factor potentially depends on the number of Z buffer bits,
|
|
|
|
* the rasterization algorithm and the arithmetic performed on Z
|
|
|
|
* values between vertex shading and rasterization. It will vary
|
|
|
|
* from one driver to another.
|
|
|
|
*/
|
|
|
|
void draw_set_mrd(struct draw_context *draw, double mrd)
|
|
|
|
{
|
|
|
|
draw->mrd = mrd;
|
|
|
|
}
|
|
|
|
|
2007-09-10 16:29:23 -06:00
|
|
|
|
2007-07-09 16:12:13 -06:00
|
|
|
/**
|
2007-09-18 10:02:16 -04:00
|
|
|
* Register new primitive rasterization/rendering state.
|
2007-07-09 16:12:13 -06:00
|
|
|
* This causes the drawing pipeline to be rebuilt.
|
|
|
|
*/
|
2007-09-18 10:02:16 -04:00
|
|
|
void draw_set_rasterizer_state( struct draw_context *draw,
|
|
|
|
const struct pipe_rasterizer_state *raster )
|
2007-07-09 16:12:13 -06:00
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
|
|
|
|
2007-09-17 12:59:50 -04:00
|
|
|
draw->rasterizer = raster;
|
2010-02-22 21:36:22 +01:00
|
|
|
draw->bypass_clipping = draw->driver.bypass_clipping;
|
2008-04-22 20:50:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void draw_set_driver_clipping( struct draw_context *draw,
|
|
|
|
boolean bypass_clipping )
|
|
|
|
{
|
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
|
|
|
|
|
|
|
draw->driver.bypass_clipping = bypass_clipping;
|
2010-02-22 21:36:22 +01:00
|
|
|
draw->bypass_clipping = draw->driver.bypass_clipping;
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2007-11-09 07:54:46 -07:00
|
|
|
* Plug in the primitive rendering/rasterization stage (which is the last
|
|
|
|
* stage in the drawing pipeline).
|
2007-07-09 16:12:13 -06:00
|
|
|
* This is provided by the device driver.
|
|
|
|
*/
|
2007-09-18 10:02:16 -04:00
|
|
|
void draw_set_rasterize_stage( struct draw_context *draw,
|
|
|
|
struct draw_stage *stage )
|
2007-07-09 16:12:13 -06:00
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
|
|
|
|
2007-09-18 10:02:16 -04:00
|
|
|
draw->pipeline.rasterize = stage;
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the draw module's clipping state.
|
|
|
|
*/
|
|
|
|
void draw_set_clip_state( struct draw_context *draw,
|
|
|
|
const struct pipe_clip_state *clip )
|
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2007-09-26 11:56:17 +01:00
|
|
|
|
2007-08-24 11:05:31 -06:00
|
|
|
assert(clip->nr <= PIPE_MAX_CLIP_PLANES);
|
2007-07-09 16:12:13 -06:00
|
|
|
memcpy(&draw->plane[6], clip->ucp, clip->nr * sizeof(clip->ucp[0]));
|
|
|
|
draw->nr_planes = 6 + clip->nr;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the draw module's viewport state.
|
|
|
|
*/
|
|
|
|
void draw_set_viewport_state( struct draw_context *draw,
|
|
|
|
const struct pipe_viewport_state *viewport )
|
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2007-07-09 16:12:13 -06:00
|
|
|
draw->viewport = *viewport; /* struct copy */
|
2008-03-31 14:14:30 -06:00
|
|
|
draw->identity_viewport = (viewport->scale[0] == 1.0f &&
|
|
|
|
viewport->scale[1] == 1.0f &&
|
|
|
|
viewport->scale[2] == 1.0f &&
|
|
|
|
viewport->scale[3] == 1.0f &&
|
|
|
|
viewport->translate[0] == 0.0f &&
|
|
|
|
viewport->translate[1] == 0.0f &&
|
|
|
|
viewport->translate[2] == 0.0f &&
|
|
|
|
viewport->translate[3] == 0.0f);
|
2008-05-29 00:17:53 +01:00
|
|
|
|
|
|
|
draw_vs_set_viewport( draw, viewport );
|
2007-07-09 16:12:13 -06:00
|
|
|
}
|
2007-08-20 15:11:11 -06:00
|
|
|
|
|
|
|
|
2007-09-06 17:07:09 -06:00
|
|
|
|
2007-08-20 15:11:11 -06:00
|
|
|
void
|
2008-03-29 14:41:03 +01:00
|
|
|
draw_set_vertex_buffers(struct draw_context *draw,
|
|
|
|
unsigned count,
|
|
|
|
const struct pipe_vertex_buffer *buffers)
|
2007-08-20 15:11:11 -06:00
|
|
|
{
|
2008-03-29 14:41:03 +01:00
|
|
|
assert(count <= PIPE_MAX_ATTRIBS);
|
|
|
|
|
2008-04-19 17:27:52 +01:00
|
|
|
memcpy(draw->pt.vertex_buffer, buffers, count * sizeof(buffers[0]));
|
|
|
|
draw->pt.nr_vertex_buffers = count;
|
2007-08-20 15:11:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2008-03-29 14:41:03 +01:00
|
|
|
draw_set_vertex_elements(struct draw_context *draw,
|
|
|
|
unsigned count,
|
|
|
|
const struct pipe_vertex_element *elements)
|
2007-08-20 15:11:11 -06:00
|
|
|
{
|
2008-03-29 14:41:03 +01:00
|
|
|
assert(count <= PIPE_MAX_ATTRIBS);
|
|
|
|
|
2008-04-19 17:27:52 +01:00
|
|
|
memcpy(draw->pt.vertex_element, elements, count * sizeof(elements[0]));
|
|
|
|
draw->pt.nr_vertex_elements = count;
|
2007-08-20 15:11:11 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-09-06 17:07:09 -06:00
|
|
|
/**
|
|
|
|
* Tell drawing context where to find mapped vertex buffers.
|
|
|
|
*/
|
2007-08-20 15:11:11 -06:00
|
|
|
void
|
2007-09-06 17:07:09 -06:00
|
|
|
draw_set_mapped_vertex_buffer(struct draw_context *draw,
|
|
|
|
unsigned attr, const void *buffer)
|
2007-08-20 15:11:11 -06:00
|
|
|
{
|
2008-04-19 17:27:52 +01:00
|
|
|
draw->pt.user.vbuffer[attr] = buffer;
|
2007-09-06 17:07:09 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
draw_set_mapped_constant_buffer(struct draw_context *draw,
|
2009-12-14 17:11:46 -05:00
|
|
|
unsigned shader_type,
|
2010-01-25 12:36:50 +01:00
|
|
|
unsigned slot,
|
2009-12-14 17:11:46 -05:00
|
|
|
const void *buffer,
|
2008-05-29 12:38:49 +01:00
|
|
|
unsigned size )
|
2007-09-06 17:07:09 -06:00
|
|
|
{
|
2009-12-14 17:11:46 -05:00
|
|
|
debug_assert(shader_type == PIPE_SHADER_VERTEX ||
|
|
|
|
shader_type == PIPE_SHADER_GEOMETRY);
|
2010-01-25 13:29:33 +01:00
|
|
|
debug_assert(slot < PIPE_MAX_CONSTANT_BUFFERS);
|
2010-01-25 12:36:50 +01:00
|
|
|
|
2009-12-14 17:11:46 -05:00
|
|
|
if (shader_type == PIPE_SHADER_VERTEX) {
|
2010-01-25 12:36:50 +01:00
|
|
|
draw->pt.user.vs_constants[slot] = buffer;
|
|
|
|
draw_vs_set_constants(draw, slot, buffer, size);
|
2009-12-14 17:11:46 -05:00
|
|
|
} else if (shader_type == PIPE_SHADER_GEOMETRY) {
|
2010-01-25 12:36:50 +01:00
|
|
|
draw->pt.user.gs_constants[slot] = buffer;
|
|
|
|
draw_gs_set_constants(draw, slot, buffer, size);
|
2009-12-14 17:11:46 -05:00
|
|
|
}
|
2007-08-20 15:11:11 -06:00
|
|
|
}
|
2007-09-06 17:07:09 -06:00
|
|
|
|
|
|
|
|
2008-01-22 10:16:30 -07:00
|
|
|
/**
|
2008-02-26 14:29:35 -07:00
|
|
|
* Tells the draw module to draw points with triangles if their size
|
|
|
|
* is greater than this threshold.
|
2008-01-22 10:16:30 -07:00
|
|
|
*/
|
|
|
|
void
|
2008-02-26 14:29:35 -07:00
|
|
|
draw_wide_point_threshold(struct draw_context *draw, float threshold)
|
2008-01-22 10:16:30 -07:00
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2008-04-19 15:29:27 +01:00
|
|
|
draw->pipeline.wide_point_threshold = threshold;
|
2008-01-22 10:16:30 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2008-02-28 17:49:22 -07:00
|
|
|
* Tells the draw module to draw lines with triangles if their width
|
|
|
|
* is greater than this threshold.
|
2008-01-22 10:16:30 -07:00
|
|
|
*/
|
|
|
|
void
|
2008-02-28 17:49:22 -07:00
|
|
|
draw_wide_line_threshold(struct draw_context *draw, float threshold)
|
2008-01-22 10:16:30 -07:00
|
|
|
{
|
2008-01-25 17:21:05 -07:00
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2008-04-19 15:29:27 +01:00
|
|
|
draw->pipeline.wide_line_threshold = threshold;
|
2008-01-22 10:16:30 -07:00
|
|
|
}
|
2007-09-26 11:56:17 +01:00
|
|
|
|
|
|
|
|
2008-03-13 14:33:57 -06:00
|
|
|
/**
|
|
|
|
* Tells the draw module whether or not to implement line stipple.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
draw_enable_line_stipple(struct draw_context *draw, boolean enable)
|
|
|
|
{
|
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2008-04-19 15:29:27 +01:00
|
|
|
draw->pipeline.line_stipple = enable;
|
2008-03-13 14:33:57 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-14 16:13:35 -06:00
|
|
|
/**
|
|
|
|
* Tells draw module whether to convert points to quads for sprite mode.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
draw_enable_point_sprites(struct draw_context *draw, boolean enable)
|
|
|
|
{
|
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
2008-04-19 15:29:27 +01:00
|
|
|
draw->pipeline.point_sprite = enable;
|
2008-03-14 16:13:35 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-06 12:22:55 +01:00
|
|
|
void
|
|
|
|
draw_set_force_passthrough( struct draw_context *draw, boolean enable )
|
|
|
|
{
|
|
|
|
draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
|
|
|
|
draw->force_passthrough = enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-18 16:19:05 -07:00
|
|
|
/**
|
2008-02-25 14:46:42 -07:00
|
|
|
* Ask the draw module for the location/slot of the given vertex attribute in
|
|
|
|
* a post-transformed vertex.
|
|
|
|
*
|
|
|
|
* With this function, drivers that use the draw module should have no reason
|
2009-12-14 17:11:46 -05:00
|
|
|
* to track the current vertex/geometry shader.
|
2008-02-25 14:46:42 -07:00
|
|
|
*
|
|
|
|
* Note that the draw module may sometimes generate vertices with extra
|
|
|
|
* attributes (such as texcoords for AA lines). The driver can call this
|
|
|
|
* function to find those attributes.
|
|
|
|
*
|
|
|
|
* Zero is returned if the attribute is not found since this is
|
|
|
|
* a don't care / undefined situtation. Returning -1 would be a bit more
|
|
|
|
* work for the drivers.
|
2008-02-18 16:19:05 -07:00
|
|
|
*/
|
|
|
|
int
|
2009-12-14 17:11:46 -05:00
|
|
|
draw_find_shader_output(const struct draw_context *draw,
|
|
|
|
uint semantic_name, uint semantic_index)
|
2008-02-18 16:19:05 -07:00
|
|
|
{
|
2008-05-13 13:40:22 +01:00
|
|
|
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
|
2009-12-14 17:11:46 -05:00
|
|
|
const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
|
2008-02-25 14:46:42 -07:00
|
|
|
uint i;
|
2009-12-14 17:11:46 -05:00
|
|
|
const struct tgsi_shader_info *info = &vs->info;
|
|
|
|
|
|
|
|
if (gs)
|
|
|
|
info = &gs->info;
|
|
|
|
|
|
|
|
for (i = 0; i < info->num_outputs; i++) {
|
|
|
|
if (info->output_semantic_name[i] == semantic_name &&
|
|
|
|
info->output_semantic_index[i] == semantic_index)
|
2008-02-25 14:46:42 -07:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2008-02-18 16:19:05 -07:00
|
|
|
/* XXX there may be more than one extra vertex attrib.
|
|
|
|
* For example, simulated gl_FragCoord and gl_PointCoord.
|
|
|
|
*/
|
2009-12-14 17:11:46 -05:00
|
|
|
if (draw->extra_shader_outputs.semantic_name == semantic_name &&
|
|
|
|
draw->extra_shader_outputs.semantic_index == semantic_index) {
|
|
|
|
return draw->extra_shader_outputs.slot;
|
2008-02-18 16:19:05 -07:00
|
|
|
}
|
2009-12-14 17:11:46 -05:00
|
|
|
|
2008-02-18 16:19:05 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-27 18:46:54 -07:00
|
|
|
/**
|
2010-02-02 18:50:19 -07:00
|
|
|
* Return total number of the shader outputs. This function is similar to
|
|
|
|
* draw_current_shader_outputs() but this function also counts any extra
|
|
|
|
* vertex/geometry output attributes that may be filled in by some draw
|
|
|
|
* stages (such as AA point, AA line).
|
2009-12-14 17:11:46 -05:00
|
|
|
*
|
|
|
|
* If geometry shader is present, its output will be returned,
|
|
|
|
* if not vertex shader is used.
|
2008-02-27 18:46:54 -07:00
|
|
|
*/
|
|
|
|
uint
|
2009-12-14 17:11:46 -05:00
|
|
|
draw_num_shader_outputs(const struct draw_context *draw)
|
2008-02-27 18:46:54 -07:00
|
|
|
{
|
2008-05-13 13:40:22 +01:00
|
|
|
uint count = draw->vs.vertex_shader->info.num_outputs;
|
2009-12-14 17:11:46 -05:00
|
|
|
|
2010-02-02 18:50:19 -07:00
|
|
|
/* If a geometry shader is present, its outputs go to the
|
|
|
|
* driver, else the vertex shader's outputs.
|
|
|
|
*/
|
2009-12-14 17:11:46 -05:00
|
|
|
if (draw->gs.geometry_shader)
|
|
|
|
count = draw->gs.geometry_shader->info.num_outputs;
|
|
|
|
|
|
|
|
if (draw->extra_shader_outputs.slot > 0)
|
2008-02-27 18:46:54 -07:00
|
|
|
count++;
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-02 22:38:46 -07:00
|
|
|
/**
|
2010-02-02 18:50:19 -07:00
|
|
|
* Provide TGSI sampler objects for vertex/geometry shaders that use
|
|
|
|
* texture fetches.
|
2008-12-02 22:38:46 -07:00
|
|
|
* This might only be used by software drivers for the time being.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
draw_texture_samplers(struct draw_context *draw,
|
|
|
|
uint num_samplers,
|
|
|
|
struct tgsi_sampler **samplers)
|
|
|
|
{
|
|
|
|
draw->vs.num_samplers = num_samplers;
|
|
|
|
draw->vs.samplers = samplers;
|
2009-12-14 17:11:46 -05:00
|
|
|
draw->gs.num_samplers = num_samplers;
|
|
|
|
draw->gs.samplers = samplers;
|
2008-12-02 22:38:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-11-07 13:07:20 +00:00
|
|
|
|
2008-03-10 19:49:15 +00:00
|
|
|
void draw_set_render( struct draw_context *draw,
|
|
|
|
struct vbuf_render *render )
|
|
|
|
{
|
|
|
|
draw->render = render;
|
|
|
|
}
|
2008-04-04 17:02:20 +01:00
|
|
|
|
2008-04-17 14:20:00 +01:00
|
|
|
|
2008-04-18 20:39:13 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tell the drawing context about the index/element buffer to use
|
|
|
|
* (ala glDrawElements)
|
|
|
|
* If no element buffer is to be used (i.e. glDrawArrays) then this
|
|
|
|
* should be called with eltSize=0 and elements=NULL.
|
|
|
|
*
|
|
|
|
* \param draw the drawing context
|
|
|
|
* \param eltSize size of each element (1, 2 or 4 bytes)
|
|
|
|
* \param elements the element buffer ptr
|
|
|
|
*/
|
|
|
|
void
|
2008-05-29 11:46:43 +01:00
|
|
|
draw_set_mapped_element_buffer_range( struct draw_context *draw,
|
|
|
|
unsigned eltSize,
|
|
|
|
unsigned min_index,
|
|
|
|
unsigned max_index,
|
2008-12-09 16:54:16 +00:00
|
|
|
const void *elements )
|
2008-04-18 20:39:13 +01:00
|
|
|
{
|
2008-04-19 17:27:52 +01:00
|
|
|
draw->pt.user.elts = elements;
|
|
|
|
draw->pt.user.eltSize = eltSize;
|
2008-05-29 11:46:43 +01:00
|
|
|
draw->pt.user.min_index = min_index;
|
|
|
|
draw->pt.user.max_index = max_index;
|
2008-04-18 20:39:13 +01:00
|
|
|
}
|
2008-04-19 15:29:27 +01:00
|
|
|
|
|
|
|
|
2008-05-29 11:46:43 +01:00
|
|
|
void
|
|
|
|
draw_set_mapped_element_buffer( struct draw_context *draw,
|
|
|
|
unsigned eltSize,
|
2008-12-09 16:54:16 +00:00
|
|
|
const void *elements )
|
2008-05-29 11:46:43 +01:00
|
|
|
{
|
|
|
|
draw->pt.user.elts = elements;
|
|
|
|
draw->pt.user.eltSize = eltSize;
|
|
|
|
draw->pt.user.min_index = 0;
|
|
|
|
draw->pt.user.max_index = 0xffffffff;
|
|
|
|
}
|
|
|
|
|
2008-04-19 15:29:27 +01:00
|
|
|
|
|
|
|
/* Revamp me please:
|
|
|
|
*/
|
|
|
|
void draw_do_flush( struct draw_context *draw, unsigned flags )
|
|
|
|
{
|
2008-04-23 18:08:20 -06:00
|
|
|
if (!draw->suspend_flushing)
|
2008-04-19 15:29:27 +01:00
|
|
|
{
|
2008-04-23 18:08:20 -06:00
|
|
|
assert(!draw->flushing); /* catch inadvertant recursion */
|
|
|
|
|
2008-04-19 15:29:27 +01:00
|
|
|
draw->flushing = TRUE;
|
|
|
|
|
2008-04-19 16:43:15 +01:00
|
|
|
draw_pipeline_flush( draw, flags );
|
|
|
|
|
|
|
|
draw->reduced_prim = ~0; /* is reduced_prim needed any more? */
|
2008-04-19 15:29:27 +01:00
|
|
|
|
|
|
|
draw->flushing = FALSE;
|
|
|
|
}
|
|
|
|
}
|
2009-12-14 17:11:46 -05:00
|
|
|
|
|
|
|
|
2010-02-02 18:50:19 -07:00
|
|
|
/**
|
|
|
|
* Return the number of output attributes produced by the geometry
|
|
|
|
* shader, if present. If no geometry shader, return the number of
|
|
|
|
* outputs from the vertex shader.
|
|
|
|
* \sa draw_num_shader_outputs
|
|
|
|
*/
|
2010-02-02 18:54:12 -07:00
|
|
|
uint
|
|
|
|
draw_current_shader_outputs(const struct draw_context *draw)
|
2009-12-14 17:11:46 -05:00
|
|
|
{
|
|
|
|
if (draw->gs.geometry_shader)
|
|
|
|
return draw->gs.num_gs_outputs;
|
|
|
|
return draw->vs.num_vs_outputs;
|
|
|
|
}
|
|
|
|
|
2010-02-02 18:50:19 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the index of the shader output which will contain the
|
|
|
|
* vertex position.
|
|
|
|
*/
|
2010-02-02 18:54:12 -07:00
|
|
|
uint
|
|
|
|
draw_current_shader_position_output(const struct draw_context *draw)
|
2009-12-14 17:11:46 -05:00
|
|
|
{
|
|
|
|
if (draw->gs.geometry_shader)
|
|
|
|
return draw->gs.position_output;
|
|
|
|
return draw->vs.position_output;
|
|
|
|
}
|