mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
This commit is contained in:
commit
9e1f7b2c57
38 changed files with 1897 additions and 249 deletions
|
|
@ -76,6 +76,8 @@ int textureWidth = 64;
|
|||
int textureHeight = 64;
|
||||
|
||||
int winWidth = 580, winHeight = 720;
|
||||
static int Win;
|
||||
|
||||
|
||||
struct formatInfo {
|
||||
GLenum baseFormat;
|
||||
|
|
@ -288,6 +290,7 @@ static void keyboard( unsigned char c, int x, int y )
|
|||
displayLevelInfo = !displayLevelInfo;
|
||||
break;
|
||||
case 27: /* Escape key should force exit. */
|
||||
glutDestroyWindow(Win);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -785,7 +788,7 @@ int main( int argc, char *argv[] )
|
|||
|
||||
glutInitWindowSize( winWidth, winHeight );
|
||||
glutInitWindowPosition( 0, 0 );
|
||||
glutCreateWindow( "Texture Environment Test" );
|
||||
Win = glutCreateWindow( "Texture Environment Test" );
|
||||
|
||||
initialize();
|
||||
instructions();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_debug.h"
|
||||
|
||||
#include "cso_cache.h"
|
||||
#include "cso_hash.h"
|
||||
|
|
@ -131,75 +132,77 @@ static int _cso_size_for_type(enum cso_cache_type type)
|
|||
static void delete_blend_state(void *state, void *data)
|
||||
{
|
||||
struct cso_blend *cso = (struct cso_blend *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static void delete_depth_stencil_state(void *state, void *data)
|
||||
{
|
||||
struct cso_depth_stencil_alpha *cso = (struct cso_depth_stencil_alpha *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static void delete_sampler_state(void *state, void *data)
|
||||
{
|
||||
struct cso_sampler *cso = (struct cso_sampler *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static void delete_rasterizer_state(void *state, void *data)
|
||||
{
|
||||
struct cso_rasterizer *cso = (struct cso_rasterizer *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static void delete_fs_state(void *state, void *data)
|
||||
{
|
||||
struct cso_fragment_shader *cso = (struct cso_fragment_shader *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static void delete_vs_state(void *state, void *data)
|
||||
{
|
||||
struct cso_vertex_shader *cso = (struct cso_vertex_shader *)state;
|
||||
if (cso->delete_state && cso->data != &cso->state)
|
||||
if (cso->delete_state)
|
||||
cso->delete_state(cso->context, cso->data);
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
|
||||
static INLINE void delete_cso(void *state, enum cso_cache_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case CSO_BLEND: {
|
||||
case CSO_BLEND:
|
||||
delete_blend_state(state, 0);
|
||||
}
|
||||
break;
|
||||
case CSO_SAMPLER: {
|
||||
case CSO_SAMPLER:
|
||||
delete_sampler_state(state, 0);
|
||||
}
|
||||
break;
|
||||
case CSO_DEPTH_STENCIL_ALPHA: {
|
||||
case CSO_DEPTH_STENCIL_ALPHA:
|
||||
delete_depth_stencil_state(state, 0);
|
||||
}
|
||||
break;
|
||||
case CSO_RASTERIZER: {
|
||||
case CSO_RASTERIZER:
|
||||
delete_rasterizer_state(state, 0);
|
||||
}
|
||||
break;
|
||||
case CSO_FRAGMENT_SHADER: {
|
||||
case CSO_FRAGMENT_SHADER:
|
||||
delete_fs_state(state, 0);
|
||||
}
|
||||
break;
|
||||
case CSO_VERTEX_SHADER: {
|
||||
case CSO_VERTEX_SHADER:
|
||||
delete_vs_state(state, 0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
FREE(state);
|
||||
}
|
||||
FREE(state);
|
||||
}
|
||||
|
||||
static INLINE void sanitize_hash(struct cso_hash *hash, enum cso_cache_type type,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ C_SOURCES = \
|
|||
draw_flatshade.c \
|
||||
draw_offset.c \
|
||||
draw_passthrough.c \
|
||||
draw_pt.c \
|
||||
draw_pt_vcache.c \
|
||||
draw_pt_fetch_emit.c \
|
||||
draw_pt_elts.c \
|
||||
draw_prim.c \
|
||||
draw_pstipple.c \
|
||||
draw_stipple.c \
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ draw = env.ConvenienceLibrary(
|
|||
'draw_debug.c',
|
||||
'draw_flatshade.c',
|
||||
'draw_offset.c',
|
||||
'draw_passthrough.c',
|
||||
'draw_passthrough.c', # going away soon
|
||||
'draw_pt.c',
|
||||
'draw_pt_vcache.c',
|
||||
'draw_pt_fetch_emit.c',
|
||||
'draw_pt_elts.c',
|
||||
'draw_prim.c',
|
||||
'draw_pstipple.c',
|
||||
'draw_stipple.c',
|
||||
|
|
|
|||
|
|
@ -621,7 +621,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
|
|||
bind_aaline_fragment_shader(aaline);
|
||||
|
||||
aaline->state.sampler[num] = aaline->sampler_cso;
|
||||
aaline->state.texture[num] = aaline->texture;
|
||||
pipe_texture_reference(&aaline->state.texture[num], aaline->texture);
|
||||
|
||||
aaline->driver_bind_sampler_states(pipe, num + 1, aaline->state.sampler);
|
||||
aaline->driver_set_sampler_textures(pipe, num + 1, aaline->state.texture);
|
||||
|
|
@ -769,9 +769,14 @@ aaline_set_sampler_textures(struct pipe_context *pipe,
|
|||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
|
||||
uint i;
|
||||
|
||||
/* save current */
|
||||
memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *));
|
||||
for (i = 0; i < num; i++) {
|
||||
pipe_texture_reference(&aaline->state.texture[i], texture[i]);
|
||||
}
|
||||
aaline->num_textures = num;
|
||||
|
||||
/* pass-through */
|
||||
aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@
|
|||
#include "draw_vbuf.h"
|
||||
|
||||
|
||||
|
||||
struct draw_context *draw_create( void )
|
||||
{
|
||||
struct draw_context *draw = CALLOC_STRUCT( draw_context );
|
||||
if (draw == NULL)
|
||||
goto fail;
|
||||
|
||||
#if defined(__i386__) || defined(__386__)
|
||||
draw->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
|
||||
|
|
@ -61,6 +62,19 @@ struct draw_context *draw_create( void )
|
|||
draw->pipeline.validate = draw_validate_stage( draw );
|
||||
draw->pipeline.first = draw->pipeline.validate;
|
||||
|
||||
if (!draw->pipeline.wide_line ||
|
||||
!draw->pipeline.wide_point ||
|
||||
!draw->pipeline.stipple ||
|
||||
!draw->pipeline.unfilled ||
|
||||
!draw->pipeline.twoside ||
|
||||
!draw->pipeline.offset ||
|
||||
!draw->pipeline.clip ||
|
||||
!draw->pipeline.flatshade ||
|
||||
!draw->pipeline.cull ||
|
||||
!draw->pipeline.validate)
|
||||
goto fail;
|
||||
|
||||
|
||||
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 );
|
||||
|
|
@ -75,6 +89,8 @@ struct draw_context *draw_create( void )
|
|||
uint i;
|
||||
const unsigned size = (MAX_VERTEX_SIZE + 0x0f) & ~0x0f;
|
||||
char *tmp = align_malloc(Elements(draw->vs.queue) * size, 16);
|
||||
if (!tmp)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < Elements(draw->vs.queue); i++)
|
||||
draw->vs.queue[i].vertex = (struct vertex_header *)(tmp + i * size);
|
||||
|
|
@ -93,22 +109,42 @@ struct draw_context *draw_create( void )
|
|||
draw_vertex_cache_invalidate( draw );
|
||||
draw_set_mapped_element_buffer( draw, 0, NULL );
|
||||
|
||||
if (!draw_pt_init( draw ))
|
||||
goto fail;
|
||||
|
||||
return draw;
|
||||
|
||||
fail:
|
||||
draw_destroy( draw );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void draw_destroy( struct draw_context *draw )
|
||||
{
|
||||
draw->pipeline.wide_line->destroy( draw->pipeline.wide_line );
|
||||
draw->pipeline.wide_point->destroy( draw->pipeline.wide_point );
|
||||
draw->pipeline.stipple->destroy( draw->pipeline.stipple );
|
||||
draw->pipeline.unfilled->destroy( draw->pipeline.unfilled );
|
||||
draw->pipeline.twoside->destroy( draw->pipeline.twoside );
|
||||
draw->pipeline.offset->destroy( draw->pipeline.offset );
|
||||
draw->pipeline.clip->destroy( draw->pipeline.clip );
|
||||
draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
|
||||
draw->pipeline.cull->destroy( draw->pipeline.cull );
|
||||
draw->pipeline.validate->destroy( draw->pipeline.validate );
|
||||
if (!draw)
|
||||
return;
|
||||
|
||||
if (draw->pipeline.wide_line)
|
||||
draw->pipeline.wide_line->destroy( draw->pipeline.wide_line );
|
||||
if (draw->pipeline.wide_point)
|
||||
draw->pipeline.wide_point->destroy( draw->pipeline.wide_point );
|
||||
if (draw->pipeline.stipple)
|
||||
draw->pipeline.stipple->destroy( draw->pipeline.stipple );
|
||||
if (draw->pipeline.unfilled)
|
||||
draw->pipeline.unfilled->destroy( draw->pipeline.unfilled );
|
||||
if (draw->pipeline.twoside)
|
||||
draw->pipeline.twoside->destroy( draw->pipeline.twoside );
|
||||
if (draw->pipeline.offset)
|
||||
draw->pipeline.offset->destroy( draw->pipeline.offset );
|
||||
if (draw->pipeline.clip)
|
||||
draw->pipeline.clip->destroy( draw->pipeline.clip );
|
||||
if (draw->pipeline.flatshade)
|
||||
draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
|
||||
if (draw->pipeline.cull)
|
||||
draw->pipeline.cull->destroy( draw->pipeline.cull );
|
||||
if (draw->pipeline.validate)
|
||||
draw->pipeline.validate->destroy( draw->pipeline.validate );
|
||||
if (draw->pipeline.aaline)
|
||||
draw->pipeline.aaline->destroy( draw->pipeline.aaline );
|
||||
if (draw->pipeline.aapoint)
|
||||
|
|
@ -117,8 +153,11 @@ void draw_destroy( struct draw_context *draw )
|
|||
draw->pipeline.pstipple->destroy( draw->pipeline.pstipple );
|
||||
if (draw->pipeline.rasterize)
|
||||
draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
|
||||
|
||||
tgsi_exec_machine_free_data(&draw->machine);
|
||||
align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */
|
||||
|
||||
if (draw->vs.queue[0].vertex)
|
||||
align_free( draw->vs.queue[0].vertex ); /* Frees all the vertices. */
|
||||
|
||||
/* Not so fast -- we're just borrowing this at the moment.
|
||||
*
|
||||
|
|
@ -126,6 +165,8 @@ void draw_destroy( struct draw_context *draw )
|
|||
draw->render->destroy( draw->render );
|
||||
*/
|
||||
|
||||
draw_pt_destroy( draw );
|
||||
|
||||
FREE( draw );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,9 +125,9 @@ fetch_store_general( struct draw_context *draw,
|
|||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
ubyte *ub = (ubyte *) from;
|
||||
attrib[0] = UBYTE_TO_FLOAT(ub[0]);
|
||||
attrib[2] = UBYTE_TO_FLOAT(ub[0]);
|
||||
attrib[1] = UBYTE_TO_FLOAT(ub[1]);
|
||||
attrib[2] = UBYTE_TO_FLOAT(ub[2]);
|
||||
attrib[0] = UBYTE_TO_FLOAT(ub[2]);
|
||||
attrib[3] = UBYTE_TO_FLOAT(ub[3]);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -526,7 +526,7 @@ draw_arrays(struct draw_context *draw, unsigned prim,
|
|||
|
||||
/* drawing done here: */
|
||||
if (!draw->rasterizer->bypass_vs ||
|
||||
!draw_passthrough_arrays(draw, prim, start, count)) {
|
||||
!draw_pt_arrays(draw, prim, start, count)) {
|
||||
/* we have to run the whole pipeline */
|
||||
draw_prim(draw, prim, start, count);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ struct pipe_context;
|
|||
struct gallivm_prog;
|
||||
struct gallivm_cpu_engine;
|
||||
|
||||
struct draw_pt_middle_end;
|
||||
struct draw_pt_front_end;
|
||||
|
||||
/**
|
||||
* Basic vertex info.
|
||||
* Carry some useful information around with the vertices in the prim pipe.
|
||||
|
|
@ -203,8 +206,21 @@ struct draw_context
|
|||
/* Support prototype passthrough path:
|
||||
*/
|
||||
struct {
|
||||
unsigned prim;
|
||||
unsigned hw_vertex_size;
|
||||
unsigned prim; /* XXX: to be removed */
|
||||
unsigned hw_vertex_size; /* XXX: to be removed */
|
||||
|
||||
struct {
|
||||
struct draw_pt_middle_end *fetch_emit;
|
||||
struct draw_pt_middle_end *fetch_shade_emit;
|
||||
struct draw_pt_middle_end *fetch_shade_cliptest_pipeline_or_emit;
|
||||
} middle;
|
||||
|
||||
struct {
|
||||
struct draw_pt_front_end *noop;
|
||||
struct draw_pt_front_end *split_arrays;
|
||||
struct draw_pt_front_end *vcache;
|
||||
} front;
|
||||
|
||||
} pt;
|
||||
|
||||
|
||||
|
|
@ -351,7 +367,18 @@ extern void draw_update_vertex_fetch( struct draw_context *draw );
|
|||
extern boolean draw_need_pipeline(const struct draw_context *draw);
|
||||
|
||||
|
||||
/* Prototype/hack
|
||||
/* Passthrough mode (second attempt):
|
||||
*/
|
||||
boolean draw_pt_init( struct draw_context *draw );
|
||||
void draw_pt_destroy( struct draw_context *draw );
|
||||
boolean draw_pt_arrays( struct draw_context *draw,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count );
|
||||
|
||||
|
||||
|
||||
/* Prototype/hack (DEPRECATED)
|
||||
*/
|
||||
boolean
|
||||
draw_passthrough_arrays(struct draw_context *draw,
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ struct pstip_fragment_shader
|
|||
struct pipe_shader_state state;
|
||||
void *driver_fs;
|
||||
void *pstip_fs;
|
||||
uint sampler_unit;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -67,7 +68,6 @@ struct pstip_stage
|
|||
struct draw_stage stage;
|
||||
|
||||
void *sampler_cso;
|
||||
uint sampler_unit;
|
||||
struct pipe_texture *texture;
|
||||
uint num_samplers;
|
||||
uint num_textures;
|
||||
|
|
@ -329,7 +329,7 @@ generate_pstip_fs(struct pstip_stage *pstip)
|
|||
tgsi_dump(pstip_fs.tokens, 0);
|
||||
#endif
|
||||
|
||||
pstip->sampler_unit = transform.maxSampler + 1;
|
||||
pstip->fs->sampler_unit = transform.maxSampler + 1;
|
||||
|
||||
pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
|
||||
}
|
||||
|
|
@ -398,6 +398,7 @@ pstip_create_texture(struct pstip_stage *pstip)
|
|||
texTemp.cpp = 1;
|
||||
|
||||
pstip->texture = screen->texture_create(screen, &texTemp);
|
||||
assert(pstip->texture->refcount == 1);
|
||||
|
||||
//pstip_update_texture(pstip);
|
||||
}
|
||||
|
|
@ -488,11 +489,14 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
|
|||
/* how many samplers? */
|
||||
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
|
||||
num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
|
||||
num_samplers = MAX2(num_samplers, pstip->sampler_unit + 1);
|
||||
num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);
|
||||
|
||||
/* plug in our sampler, texture */
|
||||
pstip->state.samplers[pstip->sampler_unit] = pstip->sampler_cso;
|
||||
pstip->state.textures[pstip->sampler_unit] = pstip->texture;
|
||||
pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso;
|
||||
pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit],
|
||||
pstip->texture);
|
||||
|
||||
assert(num_samplers <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
|
||||
pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
|
||||
|
|
@ -624,8 +628,14 @@ pstip_bind_sampler_states(struct pipe_context *pipe,
|
|||
unsigned num, void **sampler)
|
||||
{
|
||||
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
|
||||
uint i;
|
||||
|
||||
/* save current */
|
||||
memcpy(pstip->state.samplers, sampler, num * sizeof(void *));
|
||||
for (i = num; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
pstip->state.samplers[i] = NULL;
|
||||
}
|
||||
|
||||
pstip->num_samplers = num;
|
||||
/* pass-through */
|
||||
pstip->driver_bind_sampler_states(pstip->pipe, num, sampler);
|
||||
|
|
@ -637,9 +647,18 @@ pstip_set_sampler_textures(struct pipe_context *pipe,
|
|||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
|
||||
uint i;
|
||||
|
||||
/* save current */
|
||||
memcpy(pstip->state.textures, texture, num * sizeof(struct pipe_texture *));
|
||||
for (i = 0; i < num; i++) {
|
||||
pipe_texture_reference(&pstip->state.textures[i], texture[i]);
|
||||
}
|
||||
for (; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
pipe_texture_reference(&pstip->state.textures[i], NULL);
|
||||
}
|
||||
|
||||
pstip->num_textures = num;
|
||||
|
||||
/* pass-through */
|
||||
pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
|
||||
}
|
||||
|
|
|
|||
206
src/gallium/auxiliary/draw/draw_pt.c
Normal file
206
src/gallium/auxiliary/draw/draw_pt.c
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_private.h"
|
||||
#include "draw/draw_pt.h"
|
||||
|
||||
|
||||
static boolean too_many_verts( struct draw_context *draw,
|
||||
unsigned verts )
|
||||
{
|
||||
return verts < 1024;
|
||||
}
|
||||
|
||||
static boolean too_many_elts( struct draw_context *draw,
|
||||
unsigned elts )
|
||||
{
|
||||
return elts < (16 * 1024);
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
draw_pt_arrays(struct draw_context *draw,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
const boolean pipeline = draw_need_pipeline(draw);
|
||||
const boolean cliptest = !draw->rasterizer->bypass_clipping;
|
||||
const boolean shading = !draw->rasterizer->bypass_vs;
|
||||
struct draw_pt_front_end *frontend = NULL;
|
||||
struct draw_pt_middle_end *middle = NULL;
|
||||
|
||||
|
||||
/* Overall we do:
|
||||
* - frontend -- prepare fetch_elts, draw_elts - eg vcache
|
||||
* - middle -- fetch, shade, cliptest, viewport
|
||||
* - pipeline -- the prim pipeline: clipping, wide lines, etc
|
||||
* - backend -- the vbuf_render provided by the driver.
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
if (!cliptest && !pipeline && !shading) {
|
||||
/* This is the 'passthrough' path:
|
||||
*/
|
||||
/* Fetch user verts, emit hw verts:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_emit;
|
||||
}
|
||||
else if (!cliptest && !pipeline) {
|
||||
/* Fetch user verts, run vertex shader, emit hw verts:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_emit;
|
||||
}
|
||||
else if (!pipeline) {
|
||||
/* Even though !pipeline, we have to run it to get clipping. We
|
||||
* do know that the pipeline is just the clipping operation, but
|
||||
* that probably doesn't help much.
|
||||
*
|
||||
* This is going to be the most important path for a lot of
|
||||
* swtnl cards.
|
||||
*/
|
||||
/* Fetch user verts,
|
||||
* run vertex shader,
|
||||
* cliptest and viewport trasform
|
||||
* if no clipped vertices,
|
||||
* emit hw verts
|
||||
* else
|
||||
* run pipline
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_cliptest_pipeline_or_emit;
|
||||
}
|
||||
else if (!cliptest) {
|
||||
/* Fetch user verts, run vertex shader, run pipeline:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_pipeline;
|
||||
}
|
||||
else {
|
||||
/* This is what we're currently always doing:
|
||||
*/
|
||||
/* Fetch user verts, run vertex shader, cliptest, run pipeline:
|
||||
*/
|
||||
middle = draw->pt.middle.fetch_shade_cliptest_pipeline;
|
||||
}
|
||||
#else
|
||||
if (cliptest || pipeline || shading)
|
||||
return FALSE;
|
||||
|
||||
middle = draw->pt.middle.fetch_emit;
|
||||
#endif
|
||||
|
||||
|
||||
/* If !pipeline, need to make sure we respect the driver's limited
|
||||
* capabilites to receive blocks of vertex data and elements.
|
||||
*/
|
||||
#if 0
|
||||
if (!pipeline) {
|
||||
unsigned vertex_mode = passthrough;
|
||||
unsigned nr_verts = count_vertices( draw, start, count );
|
||||
unsigned hw_prim = prim;
|
||||
|
||||
if (is_elts(draw)) {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
|
||||
if (too_many_verts(nr_verts)) {
|
||||
/* if (is_verts(draw) && can_split(prim)) {
|
||||
draw = draw_arrays_split;
|
||||
}
|
||||
else */ {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
}
|
||||
|
||||
if (too_many_elts(count)) {
|
||||
|
||||
/* if (is_elts(draw) && can_split(prim)) {
|
||||
draw = draw_elts_split;
|
||||
}
|
||||
else */ {
|
||||
frontend = draw->pt.front.vcache;
|
||||
hw_prim = reduced_prim(prim);
|
||||
}
|
||||
}
|
||||
|
||||
if (!good_prim(hw_prim)) {
|
||||
draw = draw->pt.front.vcache;
|
||||
}
|
||||
}
|
||||
#else
|
||||
frontend = draw->pt.front.vcache;
|
||||
#endif
|
||||
|
||||
frontend->prepare( frontend, middle );
|
||||
|
||||
frontend->run( frontend,
|
||||
prim,
|
||||
draw_pt_elt_func( draw ),
|
||||
draw_pt_elt_ptr( draw, start ),
|
||||
count );
|
||||
|
||||
frontend->finish( frontend );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean draw_pt_init( struct draw_context *draw )
|
||||
{
|
||||
draw->pt.middle.fetch_emit = draw_pt_fetch_emit( draw );
|
||||
if (!draw->pt.middle.fetch_emit)
|
||||
return FALSE;
|
||||
|
||||
draw->pt.front.vcache = draw_pt_vcache();
|
||||
if (!draw->pt.front.vcache)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void draw_pt_destroy( struct draw_context *draw )
|
||||
{
|
||||
if (draw->pt.middle.fetch_emit) {
|
||||
draw->pt.middle.fetch_emit->destroy( draw->pt.middle.fetch_emit );
|
||||
draw->pt.middle.fetch_emit = NULL;
|
||||
}
|
||||
|
||||
if (draw->pt.front.vcache) {
|
||||
draw->pt.front.vcache->destroy( draw->pt.front.vcache );
|
||||
draw->pt.front.vcache = NULL;
|
||||
}
|
||||
}
|
||||
118
src/gallium/auxiliary/draw/draw_pt.h
Normal file
118
src/gallium/auxiliary/draw/draw_pt.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef DRAW_PT_H
|
||||
#define DRAW_PT_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
typedef unsigned (*pt_elt_func)( const void *elts, unsigned idx );
|
||||
|
||||
struct draw_pt_middle_end;
|
||||
struct draw_context;
|
||||
|
||||
/* The "front end" - prepare sets of fetch, draw elements for the
|
||||
* middle end.
|
||||
*
|
||||
* Currenly one version of this:
|
||||
* - vcache - catchall implementation, decomposes to TRI/LINE/POINT prims
|
||||
* Later:
|
||||
* - varray, varray_split
|
||||
* - velement, velement_split
|
||||
*
|
||||
* Currenly only using the vcache version.
|
||||
*/
|
||||
struct draw_pt_front_end {
|
||||
void (*prepare)( struct draw_pt_front_end *,
|
||||
struct draw_pt_middle_end * );
|
||||
|
||||
void (*run)( struct draw_pt_front_end *,
|
||||
unsigned prim,
|
||||
pt_elt_func elt_func,
|
||||
const void *elt_ptr,
|
||||
unsigned count );
|
||||
|
||||
void (*finish)( struct draw_pt_front_end * );
|
||||
void (*destroy)( struct draw_pt_front_end * );
|
||||
};
|
||||
|
||||
|
||||
/* The "middle end" - prepares actual hardware vertices for the
|
||||
* hardware backend.
|
||||
*
|
||||
* Currently two versions of this:
|
||||
* - fetch, vertex shade, cliptest, prim-pipeline
|
||||
* - fetch, emit (ie passthrough)
|
||||
* Later:
|
||||
* - fetch, vertex shade, cliptest, maybe-pipeline, maybe-emit
|
||||
* - fetch, vertex shade, emit
|
||||
*
|
||||
* Currenly only using the passthrough version.
|
||||
*/
|
||||
struct draw_pt_middle_end {
|
||||
void (*prepare)( struct draw_pt_middle_end * );
|
||||
|
||||
void (*run)( struct draw_pt_middle_end *,
|
||||
unsigned prim,
|
||||
const unsigned *fetch_elts,
|
||||
unsigned fetch_count,
|
||||
const ushort *draw_elts,
|
||||
unsigned draw_count );
|
||||
|
||||
void (*finish)( struct draw_pt_middle_end * );
|
||||
void (*destroy)( struct draw_pt_middle_end * );
|
||||
};
|
||||
|
||||
|
||||
/* The "back end" - supplied by the driver, defined in draw_vbuf.h.
|
||||
*
|
||||
* Not sure whether to wrap the prim pipeline up as an alternate
|
||||
* backend. Would be a win for everything except pure passthrough
|
||||
* mode...
|
||||
*/
|
||||
struct vbuf_render;
|
||||
|
||||
|
||||
/* Helper functions.
|
||||
*/
|
||||
pt_elt_func draw_pt_elt_func( struct draw_context *draw );
|
||||
const void *draw_pt_elt_ptr( struct draw_context *draw,
|
||||
unsigned start );
|
||||
|
||||
/* Implementations:
|
||||
*/
|
||||
struct draw_pt_front_end *draw_pt_vcache( void );
|
||||
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw );
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
88
src/gallium/auxiliary/draw/draw_pt_elts.c
Normal file
88
src/gallium/auxiliary/draw/draw_pt_elts.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "draw/draw_pt.h"
|
||||
#include "draw/draw_private.h"
|
||||
|
||||
/* Neat get_elt func that also works for varrays drawing by encoding
|
||||
* the start value into a pointer.
|
||||
*/
|
||||
|
||||
static unsigned elt_uint( const void *elts, unsigned idx )
|
||||
{
|
||||
return *(((const uint *)elts) + idx);
|
||||
}
|
||||
|
||||
static unsigned elt_ushort( const void *elts, unsigned idx )
|
||||
{
|
||||
return *(((const ushort *)elts) + idx);
|
||||
}
|
||||
|
||||
static unsigned elt_ubyte( const void *elts, unsigned idx )
|
||||
{
|
||||
return *(((const ubyte *)elts) + idx);
|
||||
}
|
||||
|
||||
static unsigned elt_vert( const void *elts, unsigned idx )
|
||||
{
|
||||
return (const ubyte *)elts - (const ubyte *)NULL + idx;
|
||||
}
|
||||
|
||||
pt_elt_func draw_pt_elt_func( struct draw_context *draw )
|
||||
{
|
||||
switch (draw->user.eltSize) {
|
||||
case 0: return elt_vert;
|
||||
case 1: return elt_ubyte;
|
||||
case 2: return elt_ushort;
|
||||
case 4: return elt_uint;
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const void *draw_pt_elt_ptr( struct draw_context *draw,
|
||||
unsigned start )
|
||||
{
|
||||
const char *elts = draw->user.elts;
|
||||
|
||||
switch (draw->user.eltSize) {
|
||||
case 0:
|
||||
return (const void *)(((const ubyte *)NULL) + start);
|
||||
case 1:
|
||||
return (const void *)(((const ubyte *)elts) + start);
|
||||
case 2:
|
||||
return (const void *)(((const ushort *)elts) + start);
|
||||
case 4:
|
||||
return (const void *)(((const uint *)elts) + start);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
364
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
Normal file
364
src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_private.h"
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "draw/draw_vertex.h"
|
||||
#include "draw/draw_pt.h"
|
||||
|
||||
/* The simplest 'middle end' in the new vertex code.
|
||||
*
|
||||
* The responsibilities of a middle end are to:
|
||||
* - perform vertex fetch using
|
||||
* - draw vertex element/buffer state
|
||||
* - a list of fetch indices we received as an input
|
||||
* - run the vertex shader
|
||||
* - cliptest,
|
||||
* - clip coord calculation
|
||||
* - viewport transformation
|
||||
* - if necessary, run the primitive pipeline, passing it:
|
||||
* - a linear array of vertex_header vertices constructed here
|
||||
* - a set of draw indices we received as an input
|
||||
* - otherwise, drive the hw backend,
|
||||
* - allocate space for hardware format vertices
|
||||
* - translate the vertex-shader output vertices to hw format
|
||||
* - calling the backend draw functions.
|
||||
*
|
||||
* For convenience, we provide a helper function to drive the hardware
|
||||
* backend given similar inputs to those required to run the pipeline.
|
||||
*
|
||||
* In the case of passthrough mode, many of these actions are disabled
|
||||
* or noops, so we end up doing:
|
||||
*
|
||||
* - perform vertex fetch
|
||||
* - drive the hw backend
|
||||
*
|
||||
* IE, basically just vertex fetch to post-vs-format vertices,
|
||||
* followed by a call to the backend helper function.
|
||||
*/
|
||||
|
||||
|
||||
struct fetch_emit_middle_end {
|
||||
struct draw_pt_middle_end base;
|
||||
struct draw_context *draw;
|
||||
|
||||
struct {
|
||||
const ubyte *ptr;
|
||||
unsigned pitch;
|
||||
void (*fetch)( const void *from, float *attrib);
|
||||
void (*emit)( const float *attrib, float **out );
|
||||
} fetch[PIPE_ATTRIB_MAX];
|
||||
|
||||
unsigned nr_fetch;
|
||||
unsigned hw_vertex_size;
|
||||
};
|
||||
|
||||
|
||||
static void fetch_B8G8R8A8_UNORM( const void *from,
|
||||
float *attrib )
|
||||
{
|
||||
ubyte *ub = (ubyte *) from;
|
||||
attrib[2] = UBYTE_TO_FLOAT(ub[0]);
|
||||
attrib[1] = UBYTE_TO_FLOAT(ub[1]);
|
||||
attrib[0] = UBYTE_TO_FLOAT(ub[2]);
|
||||
attrib[3] = UBYTE_TO_FLOAT(ub[3]);
|
||||
}
|
||||
|
||||
static void fetch_R32G32B32A32_FLOAT( const void *from,
|
||||
float *attrib )
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = f[2];
|
||||
attrib[3] = f[3];
|
||||
}
|
||||
|
||||
static void fetch_R32G32B32_FLOAT( const void *from,
|
||||
float *attrib )
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = f[2];
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
|
||||
static void fetch_R32G32_FLOAT( const void *from,
|
||||
float *attrib )
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = f[1];
|
||||
attrib[2] = 0.0;
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
|
||||
static void fetch_R32_FLOAT( const void *from,
|
||||
float *attrib )
|
||||
{
|
||||
float *f = (float *) from;
|
||||
attrib[0] = f[0];
|
||||
attrib[1] = 0.0;
|
||||
attrib[2] = 0.0;
|
||||
attrib[3] = 1.0;
|
||||
}
|
||||
|
||||
|
||||
static void emit_R32_FLOAT( const float *attrib,
|
||||
float **out )
|
||||
{
|
||||
(*out)[0] = attrib[0];
|
||||
(*out) += 1;
|
||||
}
|
||||
|
||||
static void emit_R32G32_FLOAT( const float *attrib,
|
||||
float **out )
|
||||
{
|
||||
(*out)[0] = attrib[0];
|
||||
(*out)[1] = attrib[1];
|
||||
(*out) += 2;
|
||||
}
|
||||
|
||||
static void emit_R32G32B32_FLOAT( const float *attrib,
|
||||
float **out )
|
||||
{
|
||||
(*out)[0] = attrib[0];
|
||||
(*out)[1] = attrib[1];
|
||||
(*out)[2] = attrib[2];
|
||||
(*out) += 3;
|
||||
}
|
||||
|
||||
static void emit_R32G32B32A32_FLOAT( const float *attrib,
|
||||
float **out )
|
||||
{
|
||||
(*out)[0] = attrib[0];
|
||||
(*out)[1] = attrib[1];
|
||||
(*out)[2] = attrib[2];
|
||||
(*out)[3] = attrib[3];
|
||||
(*out) += 4;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General-purpose fetch from user's vertex arrays, emit to driver's
|
||||
* vertex buffer.
|
||||
*
|
||||
* XXX this is totally temporary.
|
||||
*/
|
||||
static void
|
||||
fetch_store_general( struct fetch_emit_middle_end *feme,
|
||||
void *out_ptr,
|
||||
const unsigned *fetch_elts,
|
||||
unsigned count )
|
||||
{
|
||||
float *out = (float *)out_ptr;
|
||||
struct vbuf_render *render = feme->draw->render;
|
||||
uint i, j;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned elt = fetch_elts[i];
|
||||
|
||||
for (j = 0; j < feme->nr_fetch; j++) {
|
||||
float attrib[4];
|
||||
const ubyte *from = (feme->fetch[j].ptr +
|
||||
feme->fetch[j].pitch * elt);
|
||||
|
||||
feme->fetch[j].fetch( from, attrib );
|
||||
feme->fetch[j].emit( attrib, &out );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void fetch_emit_prepare( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
static const float zero = 0;
|
||||
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
|
||||
struct draw_context *draw = feme->draw;
|
||||
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
|
||||
unsigned nr_attrs = vinfo->num_attribs;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nr_attrs; i++) {
|
||||
unsigned src_element = vinfo->src_index[i];
|
||||
unsigned src_buffer = draw->vertex_element[src_element].vertex_buffer_index;
|
||||
|
||||
feme->fetch[i].ptr = ((const ubyte *)draw->user.vbuffer[src_buffer] +
|
||||
draw->vertex_buffer[src_buffer].buffer_offset +
|
||||
draw->vertex_element[src_element].src_offset);
|
||||
|
||||
feme->fetch[i].pitch = draw->vertex_buffer[src_buffer].pitch;
|
||||
|
||||
switch (draw->vertex_element[src_element].src_format) {
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
feme->fetch[i].fetch = fetch_B8G8R8A8_UNORM;
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
feme->fetch[i].fetch = fetch_R32G32B32A32_FLOAT;
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
feme->fetch[i].fetch = fetch_R32G32B32_FLOAT;
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32_FLOAT:
|
||||
feme->fetch[i].fetch = fetch_R32G32_FLOAT;
|
||||
break;
|
||||
case PIPE_FORMAT_R32_FLOAT:
|
||||
feme->fetch[i].fetch = fetch_R32_FLOAT;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
feme->fetch[i].fetch = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (vinfo->emit[i]) {
|
||||
case EMIT_4F:
|
||||
feme->fetch[i].emit = emit_R32G32B32A32_FLOAT;
|
||||
break;
|
||||
case EMIT_3F:
|
||||
feme->fetch[i].emit = emit_R32G32B32_FLOAT;
|
||||
break;
|
||||
case EMIT_2F:
|
||||
feme->fetch[i].emit = emit_R32G32_FLOAT;
|
||||
break;
|
||||
case EMIT_1F:
|
||||
feme->fetch[i].emit = emit_R32_FLOAT;
|
||||
break;
|
||||
case EMIT_HEADER:
|
||||
feme->fetch[i].ptr = (const ubyte *)&zero;
|
||||
feme->fetch[i].pitch = 0;
|
||||
feme->fetch[i].fetch = fetch_R32_FLOAT;
|
||||
feme->fetch[i].emit = emit_R32_FLOAT;
|
||||
break;
|
||||
case EMIT_1F_PSIZE:
|
||||
feme->fetch[i].ptr = (const ubyte *)&feme->draw->rasterizer->point_size;
|
||||
feme->fetch[i].pitch = 0;
|
||||
feme->fetch[i].fetch = fetch_R32_FLOAT;
|
||||
feme->fetch[i].emit = emit_R32_FLOAT;
|
||||
default:
|
||||
assert(0);
|
||||
feme->fetch[i].emit = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
feme->nr_fetch = nr_attrs;
|
||||
feme->hw_vertex_size = vinfo->size * 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static void fetch_emit_run( struct draw_pt_middle_end *middle,
|
||||
unsigned prim,
|
||||
const unsigned *fetch_elts,
|
||||
unsigned fetch_count,
|
||||
const ushort *draw_elts,
|
||||
unsigned draw_count )
|
||||
{
|
||||
struct fetch_emit_middle_end *feme = (struct fetch_emit_middle_end *)middle;
|
||||
struct draw_context *draw = feme->draw;
|
||||
void *hw_verts;
|
||||
boolean ok;
|
||||
|
||||
ok = draw->render->set_primitive( draw->render,
|
||||
prim );
|
||||
if (!ok) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
(ushort)feme->hw_vertex_size,
|
||||
(ushort)fetch_count );
|
||||
if (!hw_verts) {
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Single routine to fetch vertices and emit HW verts.
|
||||
*/
|
||||
fetch_store_general( feme,
|
||||
hw_verts,
|
||||
fetch_elts,
|
||||
fetch_count );
|
||||
|
||||
/* XXX: Draw arrays path to avoid re-emitting index list again and
|
||||
* again.
|
||||
*/
|
||||
draw->render->draw( draw->render,
|
||||
draw_elts,
|
||||
draw_count );
|
||||
|
||||
/* Done -- that was easy, wasn't it:
|
||||
*/
|
||||
draw->render->release_vertices( draw->render,
|
||||
hw_verts,
|
||||
feme->hw_vertex_size,
|
||||
fetch_count );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void fetch_emit_finish( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
static void fetch_emit_destroy( struct draw_pt_middle_end *middle )
|
||||
{
|
||||
FREE(middle);
|
||||
}
|
||||
|
||||
|
||||
struct draw_pt_middle_end *draw_pt_fetch_emit( struct draw_context *draw )
|
||||
{
|
||||
struct fetch_emit_middle_end *fetch_emit = CALLOC_STRUCT( fetch_emit_middle_end );
|
||||
|
||||
fetch_emit->base.prepare = fetch_emit_prepare;
|
||||
fetch_emit->base.run = fetch_emit_run;
|
||||
fetch_emit->base.finish = fetch_emit_finish;
|
||||
fetch_emit->base.destroy = fetch_emit_destroy;
|
||||
|
||||
fetch_emit->draw = draw;
|
||||
|
||||
return &fetch_emit->base;
|
||||
}
|
||||
|
||||
337
src/gallium/auxiliary/draw/draw_pt_vcache.c
Normal file
337
src/gallium/auxiliary/draw/draw_pt_vcache.c
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "pipe/p_util.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_private.h"
|
||||
//#include "draw/draw_vbuf.h"
|
||||
//#include "draw/draw_vertex.h"
|
||||
#include "draw/draw_pt.h"
|
||||
|
||||
|
||||
#define CACHE_MAX 32
|
||||
#define FETCH_MAX 128
|
||||
#define DRAW_MAX (16*1024)
|
||||
|
||||
struct vcache_frontend {
|
||||
struct draw_pt_front_end base;
|
||||
|
||||
unsigned in[CACHE_MAX];
|
||||
ushort out[CACHE_MAX];
|
||||
|
||||
ushort draw_elts[DRAW_MAX];
|
||||
unsigned fetch_elts[FETCH_MAX];
|
||||
|
||||
unsigned draw_count;
|
||||
unsigned fetch_count;
|
||||
|
||||
pt_elt_func elt_func;
|
||||
const void *elt_ptr;
|
||||
|
||||
struct draw_pt_middle_end *middle;
|
||||
unsigned output_prim;
|
||||
};
|
||||
|
||||
static void vcache_flush( struct vcache_frontend *vcache )
|
||||
{
|
||||
#if 0
|
||||
/* Should always be true if output_prim == input_prim, otherwise
|
||||
* not so much...
|
||||
*/
|
||||
unsigned i;
|
||||
for (i = 0; i < vcache->draw_count; i++) {
|
||||
assert( vcache->fetch_elts[vcache->draw_elts[i]] ==
|
||||
vcache->elt_func(vcache->elt_ptr, i) );
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vcache->draw_count) {
|
||||
vcache->middle->run( vcache->middle,
|
||||
vcache->output_prim,
|
||||
vcache->fetch_elts,
|
||||
vcache->fetch_count,
|
||||
vcache->draw_elts,
|
||||
vcache->draw_count );
|
||||
}
|
||||
|
||||
memset(vcache->in, ~0, sizeof(vcache->in));
|
||||
vcache->fetch_count = 0;
|
||||
vcache->draw_count = 0;
|
||||
}
|
||||
|
||||
static void vcache_check_flush( struct vcache_frontend *vcache )
|
||||
{
|
||||
if ( vcache->draw_count + 6 >= DRAW_MAX ||
|
||||
vcache->fetch_count + 4 >= FETCH_MAX )
|
||||
{
|
||||
vcache_flush( vcache );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void vcache_elt( struct vcache_frontend *vcache,
|
||||
unsigned felt )
|
||||
{
|
||||
unsigned idx = felt % CACHE_MAX;
|
||||
|
||||
if (vcache->in[idx] != felt) {
|
||||
assert(vcache->fetch_count < FETCH_MAX);
|
||||
|
||||
vcache->in[idx] = felt;
|
||||
vcache->out[idx] = vcache->fetch_count;
|
||||
vcache->fetch_elts[vcache->fetch_count++] = felt;
|
||||
}
|
||||
|
||||
vcache->draw_elts[vcache->draw_count++] = vcache->out[idx];
|
||||
}
|
||||
|
||||
static void vcache_triangle( struct vcache_frontend *vcache,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2 )
|
||||
{
|
||||
/* TODO: encode edgeflags in draw_elts */
|
||||
vcache_elt(vcache, i0);
|
||||
vcache_elt(vcache, i1);
|
||||
vcache_elt(vcache, i2);
|
||||
vcache_check_flush(vcache);
|
||||
}
|
||||
|
||||
static void vcache_line( struct vcache_frontend *vcache,
|
||||
boolean reset,
|
||||
unsigned i0,
|
||||
unsigned i1 )
|
||||
{
|
||||
/* TODO: encode reset-line-stipple in draw_elts */
|
||||
(void) reset;
|
||||
vcache_elt(vcache, i0);
|
||||
vcache_elt(vcache, i1);
|
||||
vcache_check_flush(vcache);
|
||||
}
|
||||
|
||||
|
||||
static void vcache_point( struct vcache_frontend *vcache,
|
||||
unsigned i0 )
|
||||
{
|
||||
vcache_elt(vcache, i0);
|
||||
vcache_check_flush(vcache);
|
||||
}
|
||||
|
||||
static void vcache_quad( struct vcache_frontend *vcache,
|
||||
unsigned i0,
|
||||
unsigned i1,
|
||||
unsigned i2,
|
||||
unsigned i3 )
|
||||
{
|
||||
vcache_triangle( vcache, i0, i1, i3 );
|
||||
vcache_triangle( vcache, i1, i2, i3 );
|
||||
}
|
||||
|
||||
|
||||
static void vcache_prepare( struct draw_pt_front_end *frontend,
|
||||
struct draw_pt_middle_end *middle )
|
||||
{
|
||||
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
|
||||
vcache->middle = middle;
|
||||
middle->prepare( middle );
|
||||
}
|
||||
|
||||
static unsigned reduced_prim[PIPE_PRIM_POLYGON + 1] = {
|
||||
PIPE_PRIM_POINTS,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_LINES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES,
|
||||
PIPE_PRIM_TRIANGLES
|
||||
};
|
||||
|
||||
|
||||
static void vcache_run( struct draw_pt_front_end *frontend,
|
||||
unsigned prim,
|
||||
pt_elt_func get_elt,
|
||||
const void *elts,
|
||||
unsigned count )
|
||||
{
|
||||
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
|
||||
unsigned i;
|
||||
|
||||
/* These are for validation only:
|
||||
*/
|
||||
vcache->elt_func = get_elt;
|
||||
vcache->elt_ptr = elts;
|
||||
vcache->output_prim = reduced_prim[prim];
|
||||
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < count; i ++) {
|
||||
vcache_point( vcache,
|
||||
get_elt(elts, i) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 0; i+1 < count; i += 2) {
|
||||
vcache_line( vcache,
|
||||
TRUE,
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (count >= 2) {
|
||||
for (i = 1; i < count; i++) {
|
||||
vcache_line( vcache,
|
||||
i == 1, /* XXX: only if vb not split */
|
||||
get_elt(elts, i - 1),
|
||||
get_elt(elts, i) );
|
||||
}
|
||||
|
||||
vcache_line( vcache,
|
||||
0,
|
||||
get_elt(elts, count - 1),
|
||||
get_elt(elts, 0) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < count; i++) {
|
||||
vcache_line( vcache,
|
||||
i == 1,
|
||||
get_elt(elts, i - 1),
|
||||
get_elt(elts, i) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
for (i = 0; i+2 < count; i += 3) {
|
||||
vcache_triangle( vcache,
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 2) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
if (i & 1) {
|
||||
vcache_triangle( vcache,
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 2) );
|
||||
}
|
||||
else {
|
||||
vcache_triangle( vcache,
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 2) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
vcache_triangle( vcache,
|
||||
get_elt(elts, 0),
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 2) );
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 0; i+3 < count; i += 4) {
|
||||
vcache_quad( vcache,
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 2),
|
||||
get_elt(elts, i + 3));
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 0; i+3 < count; i += 2) {
|
||||
vcache_quad( vcache,
|
||||
get_elt(elts, i + 2),
|
||||
get_elt(elts, i + 0),
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 3));
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
for (i = 0; i+2 < count; i++) {
|
||||
vcache_triangle( vcache,
|
||||
get_elt(elts, i + 1),
|
||||
get_elt(elts, i + 2),
|
||||
get_elt(elts, 0));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
vcache_flush( vcache );
|
||||
}
|
||||
|
||||
static void vcache_finish( struct draw_pt_front_end *frontend )
|
||||
{
|
||||
struct vcache_frontend *vcache = (struct vcache_frontend *)frontend;
|
||||
vcache->middle->finish( vcache->middle );
|
||||
vcache->middle = NULL;
|
||||
}
|
||||
|
||||
static void vcache_destroy( struct draw_pt_front_end *frontend )
|
||||
{
|
||||
FREE(frontend);
|
||||
}
|
||||
|
||||
|
||||
struct draw_pt_front_end *draw_pt_vcache( void )
|
||||
{
|
||||
struct vcache_frontend *vcache = CALLOC_STRUCT( vcache_frontend );
|
||||
|
||||
vcache->base.prepare = vcache_prepare;
|
||||
vcache->base.run = vcache_run;
|
||||
vcache->base.finish = vcache_finish;
|
||||
vcache->base.destroy = vcache_destroy;
|
||||
|
||||
memset(vcache->in, ~0, sizeof(vcache->in));
|
||||
|
||||
return &vcache->base;
|
||||
}
|
||||
|
|
@ -34,20 +34,14 @@
|
|||
|
||||
|
||||
/**
|
||||
* Check if we need any special pipeline stages, or whether prims/verts
|
||||
* can go through untouched.
|
||||
* Check if we need any special pipeline stages, or whether
|
||||
* prims/verts can go through untouched. Don't test for bypass
|
||||
* clipping or vs modes, this function is just about the primitive
|
||||
* pipeline stages.
|
||||
*/
|
||||
boolean
|
||||
draw_need_pipeline(const struct draw_context *draw)
|
||||
{
|
||||
/* clipping */
|
||||
if (!draw->rasterizer->bypass_clipping)
|
||||
return TRUE;
|
||||
|
||||
/* vertex shader */
|
||||
if (!draw->rasterizer->bypass_vs)
|
||||
return TRUE;
|
||||
|
||||
/* line stipple */
|
||||
if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
|
||||
return TRUE;
|
||||
|
|
@ -72,6 +66,11 @@ draw_need_pipeline(const struct draw_context *draw)
|
|||
if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
|
||||
return TRUE;
|
||||
|
||||
/* unfilled polygons */
|
||||
if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
|
||||
draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
|
||||
return TRUE;
|
||||
|
||||
/* polygon offset */
|
||||
if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
|
||||
return TRUE;
|
||||
|
|
@ -84,9 +83,14 @@ draw_need_pipeline(const struct draw_context *draw)
|
|||
if (draw->rasterizer->light_twoside)
|
||||
return TRUE;
|
||||
|
||||
/* polygon cull */
|
||||
/* polygon cull - this is difficult - hardware can cull just fine
|
||||
* most of the time (though sometimes CULL_NEITHER is unsupported.
|
||||
*
|
||||
* Generally this isn't a reason to require the pipeline, though.
|
||||
*
|
||||
if (draw->rasterizer->cull_mode)
|
||||
return TRUE;
|
||||
*/
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "draw_context.h"
|
||||
#include "draw_vs.h"
|
||||
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
|
||||
|
||||
static INLINE unsigned
|
||||
compute_clipmask(const float *clip, /*const*/ float plane[][4], unsigned nr)
|
||||
|
|
@ -187,6 +189,7 @@ vs_exec_run( struct draw_vertex_shader *shader,
|
|||
static void
|
||||
vs_exec_delete( struct draw_vertex_shader *dvs )
|
||||
{
|
||||
FREE((void*) dvs->state.tokens);
|
||||
FREE( dvs );
|
||||
}
|
||||
|
||||
|
|
@ -196,11 +199,13 @@ draw_create_vs_exec(struct draw_context *draw,
|
|||
const struct pipe_shader_state *state)
|
||||
{
|
||||
struct draw_vertex_shader *vs = CALLOC_STRUCT( draw_vertex_shader );
|
||||
uint nt = tgsi_num_tokens(state->tokens);
|
||||
|
||||
if (vs == NULL)
|
||||
return NULL;
|
||||
|
||||
vs->state = *state;
|
||||
/* we make a private copy of the tokens */
|
||||
vs->state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0]));
|
||||
vs->prepare = vs_exec_prepare;
|
||||
vs->run = vs_exec_run;
|
||||
vs->delete = vs_exec_delete;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "draw_context.h"
|
||||
#include "draw_vs.h"
|
||||
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
|
||||
#ifdef MESA_LLVM
|
||||
|
||||
#include "gallivm/gallivm.h"
|
||||
|
|
@ -186,6 +188,7 @@ vs_llvm_delete( struct draw_vertex_shader *base )
|
|||
/* Do something to free compiled shader:
|
||||
*/
|
||||
|
||||
FREE( (void*) shader->base.state.tokens );
|
||||
FREE( shader );
|
||||
}
|
||||
|
||||
|
|
@ -197,12 +200,14 @@ draw_create_vs_llvm(struct draw_context *draw,
|
|||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct draw_llvm_vertex_shader *vs;
|
||||
uint nt = tgsi_num_tokens(templ->tokens);
|
||||
|
||||
vs = CALLOC_STRUCT( draw_llvm_vertex_shader );
|
||||
if (vs == NULL)
|
||||
return NULL;
|
||||
|
||||
vs->base.state = templ;
|
||||
/* we make a private copy of the tokens */
|
||||
vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0]));
|
||||
vs->base.prepare = vs_llvm_prepare;
|
||||
vs->base.run = vs_llvm_run;
|
||||
vs->base.delete = vs_llvm_delete;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
|
||||
#include "rtasm/rtasm_x86sse.h"
|
||||
#include "tgsi/exec/tgsi_sse2.h"
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
|
||||
|
||||
typedef void (XSTDCALL *codegen_function) (
|
||||
|
|
@ -204,6 +205,7 @@ vs_sse_delete( struct draw_vertex_shader *base )
|
|||
|
||||
x86_release_func( &shader->sse2_program );
|
||||
|
||||
FREE( (void*) shader->base.state.tokens );
|
||||
FREE( shader );
|
||||
}
|
||||
|
||||
|
|
@ -213,6 +215,7 @@ draw_create_vs_sse(struct draw_context *draw,
|
|||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct draw_sse_vertex_shader *vs;
|
||||
uint nt = tgsi_num_tokens(templ->tokens);
|
||||
|
||||
if (!draw->use_sse)
|
||||
return NULL;
|
||||
|
|
@ -221,7 +224,8 @@ draw_create_vs_sse(struct draw_context *draw,
|
|||
if (vs == NULL)
|
||||
return NULL;
|
||||
|
||||
vs->base.state = *templ;
|
||||
/* we make a private copy of the tokens */
|
||||
vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0]));
|
||||
vs->base.prepare = vs_sse_prepare;
|
||||
vs->base.run = vs_sse_run;
|
||||
vs->base.delete = vs_sse_delete;
|
||||
|
|
|
|||
|
|
@ -317,3 +317,16 @@ tgsi_parse_token(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
tgsi_num_tokens(const struct tgsi_token *tokens)
|
||||
{
|
||||
struct tgsi_parse_context ctx;
|
||||
if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) {
|
||||
unsigned len = (ctx.FullHeader.Header.HeaderSize +
|
||||
ctx.FullHeader.Header.BodySize +
|
||||
1);
|
||||
return len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,6 +113,10 @@ void
|
|||
tgsi_parse_token(
|
||||
struct tgsi_parse_context *ctx );
|
||||
|
||||
unsigned
|
||||
tgsi_num_tokens(const struct tgsi_token *tokens);
|
||||
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ util = env.ConvenienceLibrary(
|
|||
target = 'util',
|
||||
source = [
|
||||
'p_debug.c',
|
||||
'p_debug_mem.c',
|
||||
'p_tile.c',
|
||||
'p_util.c',
|
||||
'u_blit.c',
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ int rpl_snprintf(char *str, size_t size, const char *format, ...);
|
|||
#endif
|
||||
|
||||
|
||||
void debug_vprintf(const char *format, va_list ap)
|
||||
void _debug_vprintf(const char *format, va_list ap)
|
||||
{
|
||||
#ifdef WIN32
|
||||
#ifndef WINCE
|
||||
|
|
@ -76,15 +76,7 @@ void debug_vprintf(const char *format, va_list ap)
|
|||
}
|
||||
|
||||
|
||||
void debug_printf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
debug_vprintf(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void debug_print_blob( const char *name,
|
||||
const void *blob,
|
||||
unsigned size )
|
||||
|
|
@ -99,12 +91,10 @@ void debug_print_blob( const char *name,
|
|||
debug_printf("%d:\t%08x\n", i, ublob[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* TODO: implement a debug_abort that calls EngBugCheckEx on WIN32 */
|
||||
|
||||
|
||||
static INLINE void debug_break(void)
|
||||
void _debug_break(void)
|
||||
{
|
||||
#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
|
||||
__asm("int3");
|
||||
|
|
@ -117,6 +107,150 @@ static INLINE void debug_break(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
static const char *
|
||||
find(const char *start, const char *end, char c)
|
||||
{
|
||||
const char *p;
|
||||
for(p = start; !end || p != end; ++p) {
|
||||
if(*p == c)
|
||||
return p;
|
||||
if(*p < 32)
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
compare(const char *start, const char *end, const char *s)
|
||||
{
|
||||
const char *p, *q;
|
||||
for(p = start, q = s; p != end && *q != '\0'; ++p, ++q) {
|
||||
if(*p != *q)
|
||||
return 0;
|
||||
}
|
||||
return p == end && *q == '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
copy(char *dst, const char *start, const char *end, size_t n)
|
||||
{
|
||||
const char *p;
|
||||
char *q;
|
||||
for(p = start, q = dst, n = n - 1; p != end && n; ++p, ++q, --n)
|
||||
*q = *p;
|
||||
*q = '\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
const char *
|
||||
debug_get_option(const char *name, const char *dfault)
|
||||
{
|
||||
const char *result;
|
||||
#ifdef WIN32
|
||||
ULONG_PTR iFile = 0;
|
||||
const void *pMap = NULL;
|
||||
const char *sol, *eol, *sep;
|
||||
static char output[1024];
|
||||
|
||||
pMap = EngMapFile(L"\\??\\c:\\gallium.cfg", 0, &iFile);
|
||||
if(!pMap)
|
||||
result = dfault;
|
||||
else {
|
||||
sol = (const char *)pMap;
|
||||
while(1) {
|
||||
/* TODO: handle LF line endings */
|
||||
eol = find(sol, NULL, '\r');
|
||||
if(!eol || eol == sol)
|
||||
break;
|
||||
sep = find(sol, eol, '=');
|
||||
if(!sep)
|
||||
break;
|
||||
if(compare(sol, sep, name)) {
|
||||
copy(output, sep + 1, eol, sizeof(output));
|
||||
result = output;
|
||||
break;
|
||||
}
|
||||
sol = eol + 2;
|
||||
}
|
||||
EngUnmapFile(iFile);
|
||||
}
|
||||
#else
|
||||
|
||||
result = getenv(name);
|
||||
if(!result)
|
||||
result = dfault;
|
||||
#endif
|
||||
|
||||
if(result)
|
||||
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result);
|
||||
else
|
||||
debug_printf("%s: %s = (null)\n", __FUNCTION__, name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
boolean
|
||||
debug_get_bool_option(const char *name, boolean dfault)
|
||||
{
|
||||
const char *str = debug_get_option(name, NULL);
|
||||
boolean result;
|
||||
|
||||
if(str == NULL)
|
||||
result = dfault;
|
||||
else if(!strcmp(str, "no"))
|
||||
result = FALSE;
|
||||
else if(!strcmp(str, "0"))
|
||||
result = FALSE;
|
||||
else if(!strcmp(str, "f"))
|
||||
result = FALSE;
|
||||
else if(!strcmp(str, "false"))
|
||||
result = FALSE;
|
||||
else
|
||||
result = TRUE;
|
||||
|
||||
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? "TRUE" : "FALSE");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
long
|
||||
debug_get_num_option(const char *name, long dfault)
|
||||
{
|
||||
/* FIXME */
|
||||
return dfault;
|
||||
}
|
||||
|
||||
|
||||
unsigned long
|
||||
debug_get_flags_option(const char *name,
|
||||
const struct debug_named_value *flags,
|
||||
unsigned long dfault)
|
||||
{
|
||||
unsigned long result;
|
||||
const char *str;
|
||||
|
||||
str = debug_get_option(name, NULL);
|
||||
if(!str)
|
||||
result = dfault;
|
||||
else {
|
||||
result = 0;
|
||||
while( flags->name ) {
|
||||
if (!strcmp(str, "all") || strstr(str, flags->name ))
|
||||
result |= flags->value;
|
||||
++flags;
|
||||
}
|
||||
}
|
||||
|
||||
debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
ULONG_PTR debug_config_file = 0;
|
||||
void *mapped_config_file = 0;
|
||||
|
|
@ -126,7 +260,7 @@ enum {
|
|||
};
|
||||
|
||||
/* Check for aborts enabled. */
|
||||
static unsigned abort_en()
|
||||
static unsigned abort_en(void)
|
||||
{
|
||||
if (!mapped_config_file)
|
||||
{
|
||||
|
|
@ -149,59 +283,28 @@ static unsigned abort_en()
|
|||
return ((((char *)mapped_config_file)[0]) - 0x30) & eAssertAbortEn;
|
||||
}
|
||||
#else /* WIN32 */
|
||||
static unsigned abort_en()
|
||||
static unsigned abort_en(void)
|
||||
{
|
||||
return !GETENV("GALLIUM_ABORT_ON_ASSERT");
|
||||
}
|
||||
#endif
|
||||
|
||||
void debug_assert_fail(const char *expr, const char *file, unsigned line)
|
||||
void _debug_assert_fail(const char *expr,
|
||||
const char *file,
|
||||
unsigned line,
|
||||
const char *function)
|
||||
{
|
||||
debug_printf("%s:%i: Assertion `%s' failed.\n", file, line, expr);
|
||||
_debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr);
|
||||
if (abort_en())
|
||||
{
|
||||
debug_break();
|
||||
} else
|
||||
{
|
||||
debug_printf("continuing...\n");
|
||||
_debug_printf("continuing...\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define DEBUG_MASK_TABLE_SIZE 256
|
||||
|
||||
|
||||
/**
|
||||
* Mask hash table.
|
||||
*
|
||||
* For now we just take the lower bits of the key, and do no attempt to solve
|
||||
* collisions. Use a proper hash table when we have dozens of drivers.
|
||||
*/
|
||||
static uint32_t debug_mask_table[DEBUG_MASK_TABLE_SIZE];
|
||||
|
||||
|
||||
void debug_mask_set(uint32_t uuid, uint32_t mask)
|
||||
{
|
||||
unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1);
|
||||
debug_mask_table[hash] = mask;
|
||||
}
|
||||
|
||||
|
||||
uint32_t debug_mask_get(uint32_t uuid)
|
||||
{
|
||||
unsigned hash = uuid & (DEBUG_MASK_TABLE_SIZE - 1);
|
||||
return debug_mask_table[hash];
|
||||
}
|
||||
|
||||
|
||||
void debug_mask_vprintf(uint32_t uuid, uint32_t what, const char *format, va_list ap)
|
||||
{
|
||||
uint32_t mask = debug_mask_get(uuid);
|
||||
if(mask & what)
|
||||
debug_vprintf(format, ap);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
debug_dump_enum(const struct debug_named_value *names,
|
||||
unsigned long value)
|
||||
|
|
@ -214,7 +317,7 @@ debug_dump_enum(const struct debug_named_value *names,
|
|||
++names;
|
||||
}
|
||||
|
||||
snprintf(rest, sizeof(rest), "0x%08x", value);
|
||||
snprintf(rest, sizeof(rest), "0x%08lx", value);
|
||||
return rest;
|
||||
}
|
||||
|
||||
|
|
@ -247,7 +350,7 @@ debug_dump_flags(const struct debug_named_value *names,
|
|||
else
|
||||
first = 0;
|
||||
|
||||
snprintf(rest, sizeof(rest), "0x%08x", value);
|
||||
snprintf(rest, sizeof(rest), "0x%08lx", value);
|
||||
strncat(output, rest, sizeof(output));
|
||||
}
|
||||
|
||||
|
|
|
|||
172
src/gallium/auxiliary/util/p_debug_mem.c
Normal file
172
src/gallium/auxiliary/util/p_debug_mem.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Memory debugging.
|
||||
*
|
||||
* @author José Fonseca <jrfonseca@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winddi.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "pipe/p_debug.h"
|
||||
#include "util/u_double_list.h"
|
||||
|
||||
|
||||
#define DEBUG_MEMORY_MAGIC 0x6e34090aU
|
||||
|
||||
|
||||
#if defined(WIN32) && !defined(WINCE)
|
||||
#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG')
|
||||
#define real_free(_ptr) EngFreeMem(_ptr)
|
||||
#else
|
||||
#define real_malloc(_size) malloc(_size)
|
||||
#define real_free(_ptr) free(_ptr)
|
||||
#endif
|
||||
|
||||
|
||||
struct debug_memory_header
|
||||
{
|
||||
struct list_head head;
|
||||
|
||||
unsigned long no;
|
||||
const char *file;
|
||||
unsigned line;
|
||||
const char *function;
|
||||
size_t size;
|
||||
unsigned magic;
|
||||
};
|
||||
|
||||
static struct list_head list = { &list, &list };
|
||||
|
||||
static unsigned long start_no = 0;
|
||||
static unsigned long end_no = 0;
|
||||
|
||||
|
||||
void *
|
||||
debug_malloc(const char *file, unsigned line, const char *function,
|
||||
size_t size)
|
||||
{
|
||||
struct debug_memory_header *hdr;
|
||||
|
||||
hdr = real_malloc(sizeof(*hdr) + size);
|
||||
if(!hdr)
|
||||
return NULL;
|
||||
|
||||
hdr->no = end_no++;
|
||||
hdr->file = file;
|
||||
hdr->line = line;
|
||||
hdr->function = function;
|
||||
hdr->size = size;
|
||||
hdr->magic = DEBUG_MEMORY_MAGIC;
|
||||
|
||||
LIST_ADDTAIL(&hdr->head, &list);
|
||||
|
||||
return (void *)((char *)hdr + sizeof(*hdr));
|
||||
}
|
||||
|
||||
void
|
||||
debug_free(const char *file, unsigned line, const char *function,
|
||||
void *ptr)
|
||||
{
|
||||
struct debug_memory_header *hdr;
|
||||
|
||||
if(!ptr)
|
||||
return;
|
||||
|
||||
hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr));
|
||||
if(hdr->magic != DEBUG_MEMORY_MAGIC) {
|
||||
debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n",
|
||||
file, line, function,
|
||||
ptr);
|
||||
debug_assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
LIST_DEL(&hdr->head);
|
||||
hdr->magic = 0;
|
||||
|
||||
real_free(hdr);
|
||||
}
|
||||
|
||||
void *
|
||||
debug_calloc(const char *file, unsigned line, const char *function,
|
||||
size_t count, size_t size )
|
||||
{
|
||||
void *ptr = debug_malloc( file, line, function, count * size );
|
||||
if( ptr )
|
||||
memset( ptr, 0, count * size );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
debug_realloc(const char *file, unsigned line, const char *function,
|
||||
void *old_ptr, size_t old_size, size_t new_size )
|
||||
{
|
||||
void *new_ptr = NULL;
|
||||
|
||||
if (new_size != 0) {
|
||||
new_ptr = debug_malloc( file, line, function, new_size );
|
||||
|
||||
if( new_ptr && old_ptr )
|
||||
memcpy( new_ptr, old_ptr, old_size );
|
||||
}
|
||||
|
||||
debug_free( file, line, function, old_ptr );
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void
|
||||
debug_memory_reset(void)
|
||||
{
|
||||
start_no = end_no;
|
||||
}
|
||||
|
||||
void
|
||||
debug_memory_report(void)
|
||||
{
|
||||
struct list_head *entry;
|
||||
|
||||
entry = list.prev;
|
||||
for (; entry != &list; entry = entry->prev) {
|
||||
struct debug_memory_header *hdr;
|
||||
void *ptr;
|
||||
hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
|
||||
ptr = (void *)((char *)hdr + sizeof(*hdr));
|
||||
if(hdr->no >= start_no)
|
||||
debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
|
||||
hdr->file, hdr->line, hdr->function,
|
||||
hdr->size, ptr);
|
||||
}
|
||||
}
|
||||
|
|
@ -719,8 +719,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
|
|||
ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
ctx->sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
ctx->sampler.normalized_coords = 1;
|
||||
|
||||
|
||||
|
|
@ -774,23 +772,23 @@ set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
|
|||
{
|
||||
void *buf;
|
||||
|
||||
ctx->vertices[0][0][0] = 0.0f; /*x*/
|
||||
ctx->vertices[0][0][1] = 0.0f; /*y*/
|
||||
ctx->vertices[0][0][0] = -0.5f; /*x*/
|
||||
ctx->vertices[0][0][1] = -0.5f; /*y*/
|
||||
ctx->vertices[0][1][0] = 0.0f; /*s*/
|
||||
ctx->vertices[0][1][1] = 0.0f; /*t*/
|
||||
|
||||
ctx->vertices[1][0][0] = width; /*x*/
|
||||
ctx->vertices[1][0][1] = 0.0f; /*y*/
|
||||
ctx->vertices[1][0][0] = width - 0.5f; /*x*/
|
||||
ctx->vertices[1][0][1] = -0.5f; /*y*/
|
||||
ctx->vertices[1][1][0] = 1.0f; /*s*/
|
||||
ctx->vertices[1][1][1] = 0.0f; /*t*/
|
||||
|
||||
ctx->vertices[2][0][0] = width;
|
||||
ctx->vertices[2][0][1] = height;
|
||||
ctx->vertices[2][0][0] = width - 0.5f;
|
||||
ctx->vertices[2][0][1] = height - 0.5f;
|
||||
ctx->vertices[2][1][0] = 1.0f;
|
||||
ctx->vertices[2][1][1] = 1.0f;
|
||||
|
||||
ctx->vertices[3][0][0] = 0.0f;
|
||||
ctx->vertices[3][0][1] = height;
|
||||
ctx->vertices[3][0][0] = -0.5f;
|
||||
ctx->vertices[3][0][1] = height - 0.5f;
|
||||
ctx->vertices[3][1][0] = 0.0f;
|
||||
ctx->vertices[3][1][1] = 1.0f;
|
||||
|
||||
|
|
@ -849,11 +847,13 @@ simple_viewport(struct pipe_context *pipe, uint width, uint height)
|
|||
* \param face which cube face to generate mipmaps for (0 for non-cube maps)
|
||||
* \param baseLevel the first mipmap level to use as a src
|
||||
* \param lastLevel the last mipmap level to generate
|
||||
* \param filter the minification filter used to generate mipmap levels with
|
||||
* \param filter one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST
|
||||
*/
|
||||
void
|
||||
util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
uint face, uint baseLevel, uint lastLevel, uint filter)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
|
|
@ -890,6 +890,10 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
|
|||
memset(&fb, 0, sizeof(fb));
|
||||
fb.num_cbufs = 1;
|
||||
|
||||
/* set min/mag to same filter for faster sw speed */
|
||||
ctx->sampler.mag_img_filter = filter;
|
||||
ctx->sampler.min_img_filter = filter;
|
||||
|
||||
/*
|
||||
* XXX for small mipmap levels, it may be faster to use the software
|
||||
* fallback path...
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ util_destroy_gen_mipmap(struct gen_mipmap_state *ctx);
|
|||
extern void
|
||||
util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel);
|
||||
|
||||
uint face, uint baseLevel, uint lastLevel, uint filter);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -37,6 +37,12 @@
|
|||
|
||||
#include "pipe/p_compiler.h" /* for boolean */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum pipe_format;
|
||||
|
||||
struct softpipe_winsys {
|
||||
|
|
@ -60,4 +66,8 @@ struct pipe_screen *
|
|||
softpipe_create_screen(struct pipe_winsys *);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SP_WINSYS_H */
|
||||
|
|
|
|||
|
|
@ -60,43 +60,102 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
void _debug_vprintf(const char *format, va_list ap);
|
||||
|
||||
|
||||
static INLINE void
|
||||
_debug_printf(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
_debug_vprintf(format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print debug messages.
|
||||
*
|
||||
* A debug message will be printed regardless of the DEBUG/NDEBUG macros.
|
||||
*
|
||||
* The actual channel used to output debug message is platform specific. To
|
||||
* avoid misformating or truncation, follow these rules of thumb:
|
||||
* - output whole lines
|
||||
* - avoid outputing large strings (512 bytes is the current maximum length
|
||||
* that is guaranteed to be printed in all platforms)
|
||||
*/
|
||||
void debug_printf(const char *format, ...);
|
||||
static INLINE void
|
||||
debug_printf(const char *format, ...)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
_debug_vprintf(format, ap);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Dump a blob in hex to the same place that debug_printf sends its
|
||||
* messages:
|
||||
#ifdef DEBUG
|
||||
#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap)
|
||||
#else
|
||||
#define debug_vprintf(_format, _ap) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Dump a blob in hex to the same place that debug_printf sends its
|
||||
* messages.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
void debug_print_blob( const char *name,
|
||||
const void *blob,
|
||||
unsigned size );
|
||||
#else
|
||||
#define debug_print_blob(_name, _blob, _size) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
void _debug_break(void);
|
||||
|
||||
|
||||
/**
|
||||
* @sa debug_printf
|
||||
* Hard-coded breakpoint.
|
||||
*/
|
||||
void debug_vprintf(const char *format, va_list ap);
|
||||
|
||||
void debug_assert_fail(const char *expr, const char *file, unsigned line);
|
||||
|
||||
|
||||
/** Assert macro */
|
||||
#ifdef DEBUG
|
||||
#define debug_assert(expr) ((expr) ? (void)0 : debug_assert_fail(#expr, __FILE__, __LINE__))
|
||||
#if (defined(__i386__) || defined(__386__)) && defined(__GNUC__)
|
||||
#define debug_break() __asm("int3")
|
||||
#elif (defined(__i386__) || defined(__386__)) && defined(__MSC__)
|
||||
#define debug_break() _asm {int 3}
|
||||
#else
|
||||
#define debug_break() _debug_break()
|
||||
#endif
|
||||
#else /* !DEBUG */
|
||||
#define debug_break() ((void)0)
|
||||
#endif /* !DEBUG */
|
||||
|
||||
|
||||
long
|
||||
debug_get_num_option(const char *name, long dfault);
|
||||
|
||||
void _debug_assert_fail(const char *expr,
|
||||
const char *file,
|
||||
unsigned line,
|
||||
const char *function);
|
||||
|
||||
|
||||
/**
|
||||
* Assert macro
|
||||
*
|
||||
* Do not expect that the assert call terminates -- errors must be handled
|
||||
* regardless of assert behavior.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__))
|
||||
#else
|
||||
#define debug_assert(expr) ((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/** Override standard assert macro */
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
|
@ -104,78 +163,53 @@ void debug_assert_fail(const char *expr, const char *file, unsigned line);
|
|||
|
||||
|
||||
/**
|
||||
* Set a channel's debug mask.
|
||||
*
|
||||
* uuid is just a random 32 bit integer that uniquely identifies the debugging
|
||||
* channel.
|
||||
*
|
||||
* @note Due to current implementation issues, make sure the lower 8 bits of
|
||||
* UUID are unique.
|
||||
* Output the current function name.
|
||||
*/
|
||||
void debug_mask_set(uint32_t uuid, uint32_t mask);
|
||||
|
||||
|
||||
uint32_t debug_mask_get(uint32_t uuid);
|
||||
#ifdef DEBUG
|
||||
#define debug_checkpoint() \
|
||||
_debug_printf("%s\n", __FUNCTION__)
|
||||
#else
|
||||
#define debug_checkpoint() \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Conditional debug output.
|
||||
*
|
||||
* This is just a generalization of the debug filtering mechanism used
|
||||
* throughout Gallium.
|
||||
*
|
||||
* You use this function as:
|
||||
*
|
||||
* @code
|
||||
* #define MYDRIVER_UUID 0x12345678 // random 32 bit identifier
|
||||
*
|
||||
* static void inline
|
||||
* mydriver_debug(uint32_t what, const char *format, ...)
|
||||
* {
|
||||
* #ifdef DEBUG
|
||||
* va_list ap;
|
||||
* va_start(ap, format);
|
||||
* debug_mask_vprintf(MYDRIVER_UUID, what, format, ap);
|
||||
* va_end(ap);
|
||||
* #endif
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* debug_mask_set(MYDRIVER_UUID,
|
||||
* MYDRIVER_DEBUG_THIS |
|
||||
* MYDRIVER_DEBUG_THAT |
|
||||
* ... );
|
||||
*
|
||||
* ...
|
||||
*
|
||||
* mydriver_debug(MYDRIVER_DEBUG_THIS,
|
||||
* "this and this happened\n");
|
||||
*
|
||||
* mydriver_debug(MYDRIVER_DEBUG_THAT,
|
||||
* "that = %f\n", that);
|
||||
* ...
|
||||
* @endcode
|
||||
*
|
||||
* You can also define several variants of mydriver_debug, with hardcoded what.
|
||||
* Note that although macros with variable number of arguments would accomplish
|
||||
* more in less code, they are not portable.
|
||||
* Output the full source code position.
|
||||
*/
|
||||
void debug_mask_vprintf(uint32_t uuid,
|
||||
uint32_t what,
|
||||
const char *format,
|
||||
va_list ap);
|
||||
#ifdef DEBUG
|
||||
#define debug_checkpoint_full() \
|
||||
_debug_printf("%s:%u:%s", __FILE__, __LINE__, __FUNCTION__)
|
||||
#else
|
||||
#define debug_checkpoint_full() \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Output a warning message. Muted on release version.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define debug_warning(__msg) \
|
||||
debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg))
|
||||
_debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg))
|
||||
#else
|
||||
#define debug_warning(__msg) \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Output an error message. Not muted on release version.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#define debug_error(__msg) \
|
||||
_debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, (__msg))
|
||||
#else
|
||||
#define debug_error(__msg) \
|
||||
_debug_printf("error: %s\n", __msg))
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Used by debug_dump_enum and debug_dump_flags to describe symbols.
|
||||
*/
|
||||
|
|
@ -225,6 +259,56 @@ debug_dump_flags(const struct debug_named_value *names,
|
|||
unsigned long value);
|
||||
|
||||
|
||||
/**
|
||||
* Get option.
|
||||
*
|
||||
* It is an alias for getenv on Linux.
|
||||
*
|
||||
* On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line
|
||||
* endings with one option per line as
|
||||
*
|
||||
* NAME=value
|
||||
*
|
||||
* This file must be terminated with an extra empty line.
|
||||
*/
|
||||
const char *
|
||||
debug_get_option(const char *name, const char *dfault);
|
||||
|
||||
boolean
|
||||
debug_get_bool_option(const char *name, boolean dfault);
|
||||
|
||||
long
|
||||
debug_get_unsigned_option(const char *name, long dfault);
|
||||
|
||||
unsigned long
|
||||
debug_get_flags_option(const char *name,
|
||||
const struct debug_named_value *flags,
|
||||
unsigned long dfault);
|
||||
|
||||
|
||||
void *
|
||||
debug_malloc(const char *file, unsigned line, const char *function,
|
||||
size_t size);
|
||||
|
||||
void
|
||||
debug_free(const char *file, unsigned line, const char *function,
|
||||
void *ptr);
|
||||
|
||||
void *
|
||||
debug_calloc(const char *file, unsigned line, const char *function,
|
||||
size_t count, size_t size );
|
||||
|
||||
void *
|
||||
debug_realloc(const char *file, unsigned line, const char *function,
|
||||
void *old_ptr, size_t old_size, size_t new_size );
|
||||
|
||||
void
|
||||
debug_memory_reset(void);
|
||||
|
||||
void
|
||||
debug_memory_report(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,6 +39,22 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
#if defined(WIN32) && defined(DEBUG) /* memory debugging */
|
||||
|
||||
#include "p_debug.h"
|
||||
|
||||
#define MALLOC( _size ) \
|
||||
debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size )
|
||||
#define CALLOC( _count, _size ) \
|
||||
debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size )
|
||||
#define FREE( _ptr ) \
|
||||
debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr )
|
||||
#define REALLOC( _ptr, _old_size, _size ) \
|
||||
debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size )
|
||||
#define GETENV( X ) NULL
|
||||
|
||||
#else
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
void * __stdcall
|
||||
|
|
@ -91,10 +107,10 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
|
|||
void *new_ptr = NULL;
|
||||
|
||||
if (new_size != 0) {
|
||||
unsigned copy_size = old_size < new_size ? old_size : new_size;
|
||||
new_ptr = MALLOC( new_size );
|
||||
|
||||
if( new_ptr && old_ptr ) {
|
||||
memcpy( new_ptr, old_ptr, old_size );
|
||||
if (new_ptr && old_ptr && copy_size) {
|
||||
memcpy( new_ptr, old_ptr, copy_size );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +120,7 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
|
|||
|
||||
#define GETENV( X ) NULL
|
||||
|
||||
#else /* WIN32 */
|
||||
#else /* !WIN32 */
|
||||
|
||||
#define MALLOC( SIZE ) malloc( SIZE )
|
||||
|
||||
|
|
@ -116,7 +132,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
|
|||
|
||||
#define GETENV( X ) getenv( X )
|
||||
|
||||
#endif /* WIN32 */
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !DEBUG */
|
||||
|
||||
#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T))
|
||||
|
||||
|
|
@ -184,7 +201,7 @@ mem_dup(const void *src, uint size)
|
|||
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
|
||||
#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) )
|
||||
|
||||
#define Elements(x) sizeof(x)/sizeof(*(x))
|
||||
#define Elements(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#define Offset(TYPE, MEMBER) ((unsigned)&(((TYPE *)NULL)->MEMBER))
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,28 +56,27 @@ update_textures(struct st_context *st)
|
|||
|
||||
for (unit = 0; unit < st->ctx->Const.MaxTextureCoordUnits; unit++) {
|
||||
const GLuint su = fprog->Base.SamplerUnits[unit];
|
||||
struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current;
|
||||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
struct pipe_texture *pt;
|
||||
struct pipe_texture *pt = NULL;
|
||||
|
||||
if (texObj) {
|
||||
GLboolean flush, retval;
|
||||
if (fprog->Base.SamplersUsed & (1 << su)) {
|
||||
struct gl_texture_object *texObj = st->ctx->Texture.Unit[su]._Current;
|
||||
struct st_texture_object *stObj = st_texture_object(texObj);
|
||||
|
||||
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
|
||||
if (!retval) {
|
||||
/* out of mem */
|
||||
continue;
|
||||
if (texObj) {
|
||||
GLboolean flush, retval;
|
||||
|
||||
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
|
||||
if (!retval) {
|
||||
/* out of mem */
|
||||
continue;
|
||||
}
|
||||
|
||||
st->state.num_textures = unit + 1;
|
||||
}
|
||||
|
||||
st->state.num_textures = unit + 1;
|
||||
pt = st_get_stobj_texture(stObj);
|
||||
}
|
||||
|
||||
/* XXX: need to ensure that textures are unbound/removed from
|
||||
* this table before being deleted, otherwise the pointer
|
||||
* comparison below could fail.
|
||||
*/
|
||||
|
||||
pt = st_get_stobj_texture(stObj);
|
||||
pipe_texture_reference(&st->state.sampler_texture[unit], pt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "st_atom_constbuf.h"
|
||||
#include "st_program.h"
|
||||
#include "st_cb_bitmap.h"
|
||||
#include "st_cb_program.h"
|
||||
#include "st_mesa_to_tgsi.h"
|
||||
#include "st_texture.h"
|
||||
#include "pipe/p_context.h"
|
||||
|
|
@ -406,7 +407,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
|||
assert(height <= maxSize);
|
||||
|
||||
cso_save_rasterizer(cso);
|
||||
//cso_save_viewport(cso);
|
||||
cso_save_samplers(cso);
|
||||
|
||||
/* rasterizer state: just scissor */
|
||||
{
|
||||
|
|
@ -457,11 +458,9 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
|||
/* restore state */
|
||||
cso_restore_rasterizer(cso);
|
||||
cso_restore_samplers(cso);
|
||||
//cso_restore_viewport(cso);
|
||||
/* shaders don't go through cso yet */
|
||||
pipe->bind_fs_state(pipe, st->fp->driver_shader);
|
||||
pipe->bind_vs_state(pipe, st->vp->driver_shader);
|
||||
|
||||
pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
|
||||
ctx->st->state.sampler_texture);
|
||||
}
|
||||
|
|
@ -513,7 +512,13 @@ st_destroy_bitmap(struct st_context *st)
|
|||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
|
||||
/* XXX free frag shader state */
|
||||
if (st->bitmap.combined_prog) {
|
||||
st_delete_program(st->ctx, &st->bitmap.combined_prog->Base.Base);
|
||||
}
|
||||
|
||||
if (st->bitmap.program) {
|
||||
st_delete_program(st->ctx, &st->bitmap.program->Base.Base);
|
||||
}
|
||||
|
||||
if (st->bitmap.vs) {
|
||||
pipe->delete_vs_state(pipe, st->bitmap.vs);
|
||||
|
|
|
|||
|
|
@ -523,6 +523,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
|||
|
||||
cso_save_rasterizer(cso);
|
||||
cso_save_viewport(cso);
|
||||
cso_save_samplers(cso);
|
||||
|
||||
/* rasterizer state: just scissor */
|
||||
{
|
||||
|
|
@ -596,13 +597,11 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
|
|||
/* restore state */
|
||||
cso_restore_rasterizer(cso);
|
||||
cso_restore_viewport(cso);
|
||||
cso_restore_samplers(cso);
|
||||
/* shaders don't go through cso yet */
|
||||
pipe->bind_fs_state(pipe, st->fp->driver_shader);
|
||||
pipe->bind_vs_state(pipe, st->vp->driver_shader);
|
||||
|
||||
cso_set_rasterizer(cso, &st->state.rasterizer);
|
||||
cso_set_samplers(cso, PIPE_MAX_SAMPLERS,
|
||||
(const struct pipe_sampler_state **) st->state.sampler_list);
|
||||
pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
|
||||
ctx->st->state.sampler_texture);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "st_context.h"
|
||||
#include "st_program.h"
|
||||
#include "st_atom_shader.h"
|
||||
#include "st_cb_program.h"
|
||||
|
||||
|
||||
static GLuint SerialNo = 1;
|
||||
|
|
@ -122,8 +123,8 @@ static struct gl_program *st_new_program( GLcontext *ctx,
|
|||
}
|
||||
|
||||
|
||||
static void st_delete_program( GLcontext *ctx,
|
||||
struct gl_program *prog )
|
||||
void
|
||||
st_delete_program(GLcontext *ctx, struct gl_program *prog)
|
||||
{
|
||||
struct st_context *st = st_context(ctx);
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
|
|
|
|||
|
|
@ -32,5 +32,8 @@
|
|||
extern void
|
||||
st_init_program_functions(struct dd_function_table *functions);
|
||||
|
||||
extern void
|
||||
st_delete_program(GLcontext *ctx, struct gl_program *prog);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -265,19 +265,17 @@ guess_and_alloc_texture(struct st_context *st,
|
|||
{
|
||||
GLuint firstLevel;
|
||||
GLuint lastLevel;
|
||||
GLuint width = stImage->base.Width;
|
||||
GLuint height = stImage->base.Height;
|
||||
GLuint depth = stImage->base.Depth;
|
||||
GLuint width = stImage->base.Width2; /* size w/out border */
|
||||
GLuint height = stImage->base.Height2;
|
||||
GLuint depth = stImage->base.Depth2;
|
||||
GLuint i, comp_byte = 0;
|
||||
|
||||
DBG("%s\n", __FUNCTION__);
|
||||
|
||||
assert(!stObj->pt);
|
||||
|
||||
if (stImage->base.Border)
|
||||
return;
|
||||
|
||||
if (stImage->level > stObj->base.BaseLevel &&
|
||||
if (stObj->pt &&
|
||||
stImage->level > stObj->base.BaseLevel &&
|
||||
(stImage->base.Width == 1 ||
|
||||
(stObj->base.Target != GL_TEXTURE_1D &&
|
||||
stImage->base.Height == 1) ||
|
||||
|
|
@ -297,7 +295,8 @@ guess_and_alloc_texture(struct st_context *st,
|
|||
/* Figure out image dimensions at start level.
|
||||
*/
|
||||
for (i = stImage->level; i > firstLevel; i--) {
|
||||
width <<= 1;
|
||||
if (width != 1)
|
||||
width <<= 1;
|
||||
if (height != 1)
|
||||
height <<= 1;
|
||||
if (depth != 1)
|
||||
|
|
@ -1448,9 +1447,9 @@ st_finalize_texture(GLcontext *ctx,
|
|||
stObj->pt->format !=
|
||||
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat) ||
|
||||
stObj->pt->last_level != stObj->lastLevel ||
|
||||
stObj->pt->width[0] != firstImage->base.Width ||
|
||||
stObj->pt->height[0] != firstImage->base.Height ||
|
||||
stObj->pt->depth[0] != firstImage->base.Depth ||
|
||||
stObj->pt->width[0] != firstImage->base.Width2 ||
|
||||
stObj->pt->height[0] != firstImage->base.Height2 ||
|
||||
stObj->pt->depth[0] != firstImage->base.Depth2 ||
|
||||
stObj->pt->cpp != cpp ||
|
||||
stObj->pt->compressed != firstImage->base.IsCompressed)) {
|
||||
pipe_texture_release(&stObj->pt);
|
||||
|
|
@ -1464,9 +1463,9 @@ st_finalize_texture(GLcontext *ctx,
|
|||
gl_target_to_pipe(stObj->base.Target),
|
||||
st_mesa_format_to_pipe_format(firstImage->base.TexFormat->MesaFormat),
|
||||
stObj->lastLevel,
|
||||
firstImage->base.Width,
|
||||
firstImage->base.Height,
|
||||
firstImage->base.Depth,
|
||||
firstImage->base.Width2,
|
||||
firstImage->base.Height2,
|
||||
firstImage->base.Depth2,
|
||||
comp_byte);
|
||||
if (!stObj->pt) {
|
||||
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "st_cb_drawpixels.h"
|
||||
#include "st_cb_fbo.h"
|
||||
#include "st_cb_feedback.h"
|
||||
#include "st_cb_program.h"
|
||||
#include "st_cb_queryobj.h"
|
||||
#include "st_cb_rasterpos.h"
|
||||
#include "st_cb_readpixels.h"
|
||||
|
|
|
|||
|
|
@ -92,7 +92,8 @@ st_render_mipmap(struct st_context *st,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel);
|
||||
util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel,
|
||||
PIPE_TEX_FILTER_LINEAR);
|
||||
|
||||
/* shaders don't go through CSO yet */
|
||||
if (st->fp)
|
||||
|
|
|
|||
|
|
@ -97,10 +97,6 @@ struct st_vertex_program
|
|||
};
|
||||
|
||||
|
||||
extern void
|
||||
st_init_program_functions(struct dd_function_table *functions);
|
||||
|
||||
|
||||
static inline struct st_fragment_program *
|
||||
st_fragment_program( struct gl_fragment_program *fp )
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue