Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1

This commit is contained in:
Ben Skeggs 2008-01-02 23:02:35 +11:00
commit 720fd7b5e9
35 changed files with 865 additions and 139 deletions

View file

@ -554,8 +554,13 @@ alloc_shared_state( GLcontext *ctx )
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultCubeMap);
if (ss->DefaultRect)
(*ctx->Driver.DeleteTexture)(ctx, ss->DefaultRect);
if (ss)
_mesa_free(ss);
if (ss->Default1DArray)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default1DArray);
if (ss->Default2DArray)
(*ctx->Driver.DeleteTexture)(ctx, ss->Default2DArray);
_mesa_free(ss);
return GL_FALSE;
}
@ -678,6 +683,9 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
ctx->Driver.DeleteTexture(ctx, ss->Default3D);
ctx->Driver.DeleteTexture(ctx, ss->DefaultCubeMap);
ctx->Driver.DeleteTexture(ctx, ss->DefaultRect);
ctx->Driver.DeleteTexture(ctx, ss->Default1DArray);
ctx->Driver.DeleteTexture(ctx, ss->Default2DArray);
/* all other textures */
_mesa_HashDeleteAll(ss->TexObjects, delete_texture_cb, ctx);
_mesa_DeleteHashTable(ss->TexObjects);

View file

@ -1,6 +1,6 @@
/**************************************************************************
*
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -1529,6 +1529,8 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx)
prog = (struct gl_vertex_program *)
ctx->Driver.NewProgram(ctx, GL_VERTEX_PROGRAM_ARB, 0);
if (!prog)
return NULL;
create_new_program( key, prog,
ctx->Const.VertexProgram.MaxTemps );
@ -1541,10 +1543,8 @@ _mesa_get_fixed_func_vertex_program(GLcontext *ctx)
_mesa_program_cache_insert(ctx, ctx->VertexProgram.Cache,
key, sizeof(*key), &prog->Base);
}
else {
/* use cached program */
_mesa_free(key);
}
_mesa_free(key);
return prog;
}

View file

@ -17,9 +17,12 @@ SPU_CODE_MODULE = ../spu/g3d_spu.a
SOURCES = \
cell_context.c \
cell_draw_arrays.c \
cell_flush.c \
cell_render.c \
cell_state_blend.c \
cell_state_clip.c \
cell_state_derived.c \
cell_state_fs.c \
cell_state_rasterizer.c \
cell_state_sampler.c \

View file

@ -40,7 +40,9 @@
#include "pipe/cell/common.h"
#include "pipe/draw/draw_context.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_flush.h"
#include "cell_render.h"
#include "cell_state.h"
#include "cell_surface.h"
#include "cell_spu.h"
@ -212,12 +214,9 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
cell->pipe.set_vertex_buffer = cell_set_vertex_buffer;
cell->pipe.set_vertex_element = cell_set_vertex_element;
#if 0
cell->pipe.set_feedback_buffer = cell_set_feedback_buffer;
cell->pipe.draw_arrays = cell_draw_arrays;
cell->pipe.draw_elements = cell_draw_elements;
#endif
cell->pipe.clear = cell_clear_surface;
cell->pipe.flush = cell_flush;
@ -235,6 +234,10 @@ cell_create_context(struct pipe_winsys *winsys, struct cell_winsys *cws)
cell->draw = draw_create();
cell->render_stage = cell_draw_render_stage(cell);
draw_set_rasterize_stage(cell->draw, cell->render_stage);
/*
* SPU stuff
*/

View file

@ -31,9 +31,25 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/draw/draw_vertex.h"
#include "cell_winsys.h"
struct cell_vertex_shader_state
{
struct pipe_shader_state shader;
void *draw_data;
};
struct cell_fragment_shader_state
{
struct pipe_shader_state shader;
void *data;
};
struct cell_context
{
struct pipe_context pipe;
@ -44,6 +60,8 @@ struct cell_context
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct pipe_depth_stencil_alpha_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;
const struct cell_vertex_shader_state *vs;
const struct cell_fragment_shader_state *fs;
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
@ -55,13 +73,20 @@ struct cell_context
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
uint dirty;
/** The primitive drawing context */
struct draw_context *draw;
struct draw_stage *setup;
struct draw_stage *render_stage;
struct draw_stage *vbuf;
struct vertex_info vertex_info;
/** Mapped constant buffers */
void *mapped_constants[PIPE_SHADER_TYPES];
uint num_spus;

View file

@ -0,0 +1,169 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/* Author:
* Brian Paul
* Keith Whitwell
*/
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
#include "pipe/p_winsys.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_state.h"
#include "pipe/draw/draw_context.h"
static void
cell_map_constant_buffers(struct cell_context *sp)
{
struct pipe_winsys *ws = sp->pipe.winsys;
uint i;
for (i = 0; i < 2; i++) {
if (sp->constants[i].size)
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer,
PIPE_BUFFER_FLAG_READ);
}
draw_set_mapped_constant_buffer(sp->draw,
sp->mapped_constants[PIPE_SHADER_VERTEX]);
}
static void
cell_unmap_constant_buffers(struct cell_context *sp)
{
struct pipe_winsys *ws = sp->pipe.winsys;
uint i;
for (i = 0; i < 2; i++) {
if (sp->constants[i].size)
ws->buffer_unmap(ws, sp->constants[i].buffer);
sp->mapped_constants[i] = NULL;
}
}
boolean
cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count)
{
return cell_draw_elements(pipe, NULL, 0, mode, start, count);
}
/**
* Draw vertex arrays, with optional indexing.
* Basically, map the vertex buffers (and drawing surfaces), then hand off
* the drawing to the 'draw' module.
*
* XXX should the element buffer be specified/bound with a separate function?
*/
boolean
cell_draw_elements(struct pipe_context *pipe,
struct pipe_buffer_handle *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
struct cell_context *sp = cell_context(pipe);
struct draw_context *draw = sp->draw;
unsigned i;
/* first, check that the primitive is not malformed. It is the
* state tracker's responsibility to do send only correctly formed
* primitives down. It currently isn't doing that though...
*/
#if 1
count = draw_trim_prim( mode, count );
#else
if (!draw_validate_prim( mode, count ))
assert(0);
#endif
if (sp->dirty)
cell_update_derived( sp );
#if 0
cell_map_surfaces(sp);
#endif
cell_map_constant_buffers(sp);
/*
* Map vertex buffers
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (sp->vertex_buffer[i].buffer) {
void *buf
= pipe->winsys->buffer_map(pipe->winsys,
sp->vertex_buffer[i].buffer,
PIPE_BUFFER_FLAG_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
}
/* Map index buffer, if present */
if (indexBuffer) {
void *mapped_indexes
= pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
PIPE_BUFFER_FLAG_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
/* no index/element buffer */
draw_set_mapped_element_buffer(draw, 0, NULL);
}
/* draw! */
draw_arrays(draw, mode, start, count);
/* always flush for now */
draw_flush(draw);
/*
* unmap vertex/index buffers
*/
for (i = 0; i < PIPE_ATTRIB_MAX; i++) {
if (sp->vertex_buffer[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys, sp->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (indexBuffer) {
pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
/* Note: leave drawing surfaces mapped */
cell_unmap_constant_buffers(sp);
return TRUE;
}

View file

@ -0,0 +1,42 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#ifndef CELL_DRAW_ARRAYS_H
#define CELL_DRAW_ARRAYS_H
boolean cell_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
boolean cell_draw_elements(struct pipe_context *pipe,
struct pipe_buffer_handle *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
#endif /* CELL_DRAW_ARRAYS_H */

View file

@ -0,0 +1,129 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/**
* \brief Last stage of 'draw' pipeline: send tris to SPUs.
* \author Brian Paul
*/
#include "cell_context.h"
#include "cell_render.h"
#include "pipe/p_util.h"
#include "pipe/draw/draw_private.h"
struct render_stage {
struct draw_stage stage; /**< This must be first (base class) */
struct cell_context *cell;
};
static INLINE struct render_stage *
render_stage(struct draw_stage *stage)
{
return (struct render_stage *) stage;
}
static void render_begin( struct draw_stage *stage )
{
#if 0
struct render_stage *render = render_stage(stage);
struct cell_context *sp = render->cell;
const struct pipe_shader_state *fs = &render->cell->fs->shader;
render->quad.nr_attrs = render->cell->nr_frag_attrs;
render->firstFpInput = fs->input_semantic_name[0];
sp->quad.first->begin(sp->quad.first);
#endif
}
static void render_end( struct draw_stage *stage )
{
}
static void reset_stipple_counter( struct draw_stage *stage )
{
struct render_stage *render = render_stage(stage);
/*render->cell->line_stipple_counter = 0;*/
}
static void
render_point(struct draw_stage *stage, struct prim_header *prim)
{
}
static void
render_line(struct draw_stage *stage, struct prim_header *prim)
{
}
static void
render_tri(struct draw_stage *stage, struct prim_header *prim)
{
printf("Cell render tri\n");
}
static void render_destroy( struct draw_stage *stage )
{
FREE( stage );
}
/**
* Create a new draw/render stage. This will be plugged into the
* draw module as the last pipeline stage.
*/
struct draw_stage *cell_draw_render_stage( struct cell_context *cell )
{
struct render_stage *render = CALLOC_STRUCT(render_stage);
render->cell = cell;
render->stage.draw = cell->draw;
render->stage.begin = render_begin;
render->stage.point = render_point;
render->stage.line = render_line;
render->stage.tri = render_tri;
render->stage.end = render_end;
render->stage.reset_stipple_counter = reset_stipple_counter;
render->stage.destroy = render_destroy;
/*
render->quad.coef = render->coef;
render->quad.posCoef = &render->posCoef;
*/
return &render->stage;
}

View file

@ -0,0 +1,36 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#ifndef CELL_RENDER_H
#define CELL_RENDER_H
struct cell_context;
struct draw_stage;
extern struct draw_stage *cell_draw_render_stage( struct cell_context *cell );
#endif /* CELL_RENDER_H */

View file

@ -104,4 +104,6 @@ void cell_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void cell_update_derived( struct cell_context *softpipe );
#endif

View file

@ -0,0 +1,222 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#include "pipe/p_util.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/draw/draw_context.h"
#include "pipe/draw/draw_vertex.h"
#include "cell_context.h"
#include "cell_state.h"
/**
* Determine which post-transform / pre-rasterization vertex attributes
* we need.
* Derived from: fs, setup states.
*/
static void calculate_vertex_layout( struct cell_context *cell )
{
#if 0
const struct pipe_shader_state *vs = cell->vs->state;
const struct pipe_shader_state *fs = &cell->fs->shader;
const enum interp_mode colorInterp
= cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &cell->vertex_info;
boolean emitBack0 = FALSE, emitBack1 = FALSE, emitPsize = FALSE;
uint front0 = 0, back0 = 0, front1 = 0, back1 = 0;
uint i;
#endif
const enum interp_mode colorInterp
= cell->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
struct vertex_info *vinfo = &cell->vertex_info;
uint front0;
memset(vinfo, 0, sizeof(*vinfo));
#if 0
if (fs->input_semantic_name[0] == TGSI_SEMANTIC_POSITION) {
/* Need Z if depth test is enabled or the fragment program uses the
* fragment position (XYZW).
*/
}
cell->psize_slot = -1;
#endif
/* always emit vertex pos */
draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_LINEAR);
#if 1
front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp);
#endif
#if 0
/*
* XXX I think we need to reconcile the vertex shader outputs with
* the fragment shader inputs here to make sure the slots line up.
* Might just be getting lucky so far.
* Or maybe do that in the state tracker?
*/
for (i = 0; i < vs->num_outputs; i++) {
switch (vs->output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
/* vertex programs always emit position, but might not be
* needed for fragment progs.
*/
/* no-op */
break;
case TGSI_SEMANTIC_COLOR:
if (vs->output_semantic_index[i] == 0) {
front0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp);
}
else {
assert(vs->output_semantic_index[i] == 1);
front1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp);
}
break;
case TGSI_SEMANTIC_BCOLOR:
if (vs->output_semantic_index[i] == 0) {
emitBack0 = TRUE;
}
else {
assert(vs->output_semantic_index[i] == 1);
emitBack1 = TRUE;
}
break;
case TGSI_SEMANTIC_FOG:
draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_PERSPECTIVE);
break;
case TGSI_SEMANTIC_PSIZE:
/* XXX only emit if drawing points or front/back polygon mode
* is point mode
*/
emitPsize = TRUE;
break;
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
draw_emit_vertex_attr(vinfo, FORMAT_4F, INTERP_PERSPECTIVE);
break;
default:
assert(0);
}
}
cell->nr_frag_attrs = fs->num_inputs;
/* We want these after all other attribs since they won't get passed
* to the fragment shader. All prior vertex output attribs should match
* up 1:1 with the fragment shader inputs.
*/
if (emitBack0) {
back0 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp);
}
if (emitBack1) {
back1 = draw_emit_vertex_attr(vinfo, FORMAT_4F, colorInterp);
}
if (emitPsize) {
cell->psize_slot
= draw_emit_vertex_attr(vinfo, FORMAT_1F, INTERP_CONSTANT);
}
/* If the attributes have changed, tell the draw module about
* the new vertex layout.
*/
/* XXX we also need to do this when the shading mode (interp modes) change: */
#endif
if (1/*vinfo->attr_mask != cell->attr_mask*/) {
/*cell->attr_mask = vinfo->attr_mask;*/
draw_set_vertex_info( cell->draw, vinfo);
#if 0
draw_set_twoside_attributes(cell->draw,
front0, back0, front1, back1);
#endif
}
}
#if 0
/**
* Recompute cliprect from scissor bounds, scissor enable and surface size.
*/
static void
compute_cliprect(struct cell_context *sp)
{
unsigned surfWidth, surfHeight;
if (sp->framebuffer.num_cbufs > 0) {
surfWidth = sp->framebuffer.cbufs[0]->width;
surfHeight = sp->framebuffer.cbufs[0]->height;
}
else {
/* no surface? */
surfWidth = sp->scissor.maxx;
surfHeight = sp->scissor.maxy;
}
if (sp->rasterizer->scissor) {
/* clip to scissor rect */
sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
sp->cliprect.maxy = MIN2(sp->scissor.maxy, surfHeight);
}
else {
/* clip to surface bounds */
sp->cliprect.minx = 0;
sp->cliprect.miny = 0;
sp->cliprect.maxx = surfWidth;
sp->cliprect.maxy = surfHeight;
}
}
#endif
void cell_update_derived( struct cell_context *cell )
{
if (cell->dirty & (CELL_NEW_RASTERIZER | CELL_NEW_FS))
calculate_vertex_layout( cell );
#if 0
if (cell->dirty & (CELL_NEW_SCISSOR |
CELL_NEW_DEPTH_STENCIL_ALPHA |
CELL_NEW_FRAMEBUFFER))
compute_cliprect(cell);
#endif
cell->dirty = 0;
}

View file

@ -28,8 +28,8 @@
#include "pipe/p_defines.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#if 0
#include "pipe/draw/draw_context.h"
#if 0
#include "pipe/p_shader_tokens.h"
#include "pipe/llvm/gallivm.h"
#include "pipe/tgsi/util/tgsi_dump.h"
@ -40,25 +40,22 @@
#include "cell_state.h"
void * cell_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
void *
cell_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
struct cell_context *cell = cell_context(pipe);
struct cell_fragment_shader_state *state;
return malloc(5); /* XXX temp */
state = CALLOC_STRUCT(cell_fragment_shader_state);
if (!state)
return NULL;
#if 0
/* Decide whether we'll be codegenerating this shader and if so do
* that now.
*/
struct sp_fragment_shader_state *state = MALLOC( sizeof(struct sp_fragment_shader_state) );
state->shader = *templ;
if( cell->dump_fs ) {
tgsi_dump(
state->shader.tokens,
0 );
#if 0
if (cell->dump_fs) {
tgsi_dump(state->shader.tokens, 0);
}
#if defined(__i386__) || defined(__386__)
@ -76,32 +73,32 @@ void * cell_create_fs_state(struct pipe_context *pipe,
else
gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog);
#endif
return state;
#endif
return state;
}
void cell_bind_fs_state(struct pipe_context *pipe, void *fs)
void
cell_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct cell_context *cell = cell_context(pipe);
#if 0
cell->fs = (struct sp_fragment_shader_state *) fs;
cell->dirty |= SP_NEW_FS;
#endif
cell->fs = (struct cell_fragment_shader_state *) fs;
cell->dirty |= CELL_NEW_FS;
}
void cell_delete_fs_state(struct pipe_context *pipe,
void *shader)
{
#if 0
struct sp_fragment_shader_state *state = shader;
#if defined(__i386__) || defined(__386__)
x86_release_func( &state->sse2_program );
#endif
void
cell_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct cell_context *cell = cell_context(pipe);
struct cell_fragment_shader_state *state =
(struct cell_fragment_shader_state *) fs;
FREE( state );
#endif
}
@ -109,73 +106,56 @@ void *
cell_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
return malloc(5); /* XXX */
#if 0
struct cell_context *cell = cell_context(pipe);
struct sp_vertex_shader_state *state;
struct cell_vertex_shader_state *state;
state = MALLOC( sizeof(struct sp_vertex_shader_state) );
if (state == NULL ) {
state = CALLOC_STRUCT(cell_vertex_shader_state);
if (!state)
return NULL;
}
state->state = MALLOC( sizeof(struct pipe_shader_state) );
if (state->state == NULL) {
FREE( state );
return NULL;
}
memcpy( state->state, templ, sizeof(struct pipe_shader_state) );
state->shader = *templ;
state->draw_data = draw_create_vertex_shader(cell->draw,
state->state);
state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader);
if (state->draw_data == NULL) {
FREE( state->state );
FREE( state );
return NULL;
}
return state;
#endif
}
void
cell_bind_vs_state(struct pipe_context *pipe, void *vs)
{
#if 0
struct cell_context *cell = cell_context(pipe);
cell->vs = (const struct sp_vertex_shader_state *)vs;
cell->vs = (const struct cell_vertex_shader_state *) vs;
draw_bind_vertex_shader(cell->draw, cell->vs->draw_data);
cell->dirty |= SP_NEW_VS;
#endif
cell->dirty |= CELL_NEW_VS;
}
void
cell_delete_vs_state(struct pipe_context *pipe, void *vs)
{
#if 0
struct cell_context *cell = cell_context(pipe);
struct sp_vertex_shader_state *state =
(struct sp_vertex_shader_state *)vs;
struct cell_vertex_shader_state *state =
(struct cell_vertex_shader_state *) vs;
draw_delete_vertex_shader(cell->draw, state->draw_data);
FREE( state->state );
FREE( state );
#endif
}
void cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
void
cell_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
{
#if 0
struct cell_context *cell = cell_context(pipe);
struct pipe_winsys *ws = pipe->winsys;
@ -188,8 +168,5 @@ void cell_set_constant_buffer(struct pipe_context *pipe,
buf->buffer);
cell->constants[shader].size = buf->size;
cell->dirty |= SP_NEW_CONSTANTS;
#endif
cell->dirty |= CELL_NEW_CONSTANTS;
}

View file

@ -42,6 +42,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_format.h"
#include "pipe/p_util.h"
#include "main.h"
#include "tri.h"
@ -235,8 +236,16 @@ pack_color(const float color[4])
uint g = (uint) (color[1] * 255.0);
uint b = (uint) (color[2] * 255.0);
uint a = (uint) (color[3] * 255.0);
uint icolor = (b << 24) | (g << 16) | (r << 8) | a;
return icolor;
const enum pipe_format format = PIPE_FORMAT_A8R8G8B8_UNORM; /* XXX temp */
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
return (a << 24) | (r << 16) | (g << 8) | b;
case PIPE_FORMAT_B8G8R8A8_UNORM:
return (b << 24) | (g << 16) | (r << 8) | a;
default:
assert(0);
return 0;
}
}

View file

@ -101,8 +101,15 @@ static void *cso_data_allocate_node(struct cso_hash_data *hash)
return malloc(hash->nodeSize);
}
static void cso_data_free_node(void *node)
static void cso_data_free_node(struct cso_node *node)
{
/* XXX still a leak here.
* Need to cast value ptr to original cso type, then free the
* driver-specific data hanging off of it. For example:
struct cso_sampler *csamp = (struct cso_sampler *) node->value;
free(csamp->data);
*/
free(node->value);
free(node);
}

View file

@ -102,6 +102,7 @@ void draw_destroy( struct draw_context *draw )
draw->pipeline.validate->destroy( draw->pipeline.validate );
if (draw->pipeline.rasterize)
draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
tgsi_exec_machine_free_data(&draw->machine);
FREE( draw->vcache.vertex[0] ); /* Frees all the vertices. */
FREE( draw );
}

View file

@ -329,6 +329,7 @@ struct brw_vs_prog_data {
float imm_buf[PIPE_MAX_CONSTANT][4];
unsigned num_imm;
unsigned num_consts;
/* Used for calculating urb partitions:
*/

View file

@ -252,9 +252,14 @@ static void upload_constant_buffer(struct brw_context *brw)
/*unsigned nr = vp->max_const;*/
const struct pipe_constant_buffer *cbuffer = brw->attribs.Constants[0];
struct pipe_winsys *ws = brw->pipe.winsys;
if (cbuffer->size) {
/* FIXME: buffer size is num_consts + num_immediates */
if (brw->vs.prog_data->num_consts) {
/* map the vertex constant buffer and copy to curbe: */
ws->buffer_map(ws, cbuffer->buffer, 0);
/* FIXME: this is wrong. the cbuffer->size currently
* represents size of consts + immediates. so if we'll
* have both we'll copy over the end of the buffer
* with the subsequent memcpy */
ws->buffer_get_subdata(ws, cbuffer->buffer,
0,
cbuffer->size,
@ -263,12 +268,10 @@ static void upload_constant_buffer(struct brw_context *brw)
offset += cbuffer->size;
}
/*immediates*/
#if 0
if (brw->vs.prog_data->num_imm) {
memcpy(&buf[offset], brw->vs.prog_data->imm_buf,
brw->vs.prog_data->num_imm * 4 * sizeof(float));
}
#endif
}
if (1) {

View file

@ -630,6 +630,8 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
case TGSI_FILE_CONSTANT:
assert(c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_consts].nr != 0);
return c->regs[TGSI_FILE_CONSTANT][index + c->prog_data.num_consts];
case TGSI_FILE_IMMEDIATE:
assert(c->regs[TGSI_FILE_CONSTANT][index].nr != 0);
return c->regs[TGSI_FILE_CONSTANT][index];
@ -1317,6 +1319,7 @@ void brw_vs_emit(struct brw_vs_compile *c)
/* first instruction (declerations finished).
* now that we know what vars are being used allocate
* registers for them.*/
c->prog_data.num_consts = prog_info.num_consts;
c->prog_data.max_const = prog_info.num_consts + c->prog_data.num_imm;
brw_vs_alloc_regs(c, &prog_info);

View file

@ -127,6 +127,8 @@ softpipe_unmap_surfaces(struct softpipe_context *sp)
static void softpipe_destroy( struct pipe_context *pipe )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
struct pipe_winsys *ws = pipe->winsys;
uint i;
draw_destroy( softpipe->draw );
@ -143,6 +145,20 @@ static void softpipe_destroy( struct pipe_context *pipe )
softpipe->quad.colormask->destroy( softpipe->quad.colormask );
softpipe->quad.output->destroy( softpipe->quad.output );
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
sp_destroy_tile_cache(softpipe->zbuf_cache);
sp_destroy_tile_cache(softpipe->sbuf_cache_sep);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
sp_destroy_tile_cache(softpipe->tex_cache[i]);
for (i = 0; i < Elements(softpipe->constants); i++) {
if (softpipe->constants[i].buffer) {
ws->buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
}
}
FREE( softpipe );
}

View file

@ -43,29 +43,10 @@ struct softpipe_winsys;
struct draw_context;
struct draw_stage;
struct softpipe_tile_cache;
struct sp_fragment_shader_state;
struct sp_vertex_shader_state;
#define SP_NEW_VIEWPORT 0x1
#define SP_NEW_RASTERIZER 0x2
#define SP_NEW_FS 0x4
#define SP_NEW_BLEND 0x8
#define SP_NEW_CLIP 0x10
#define SP_NEW_SCISSOR 0x20
#define SP_NEW_STIPPLE 0x40
#define SP_NEW_FRAMEBUFFER 0x80
#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
#define SP_NEW_CONSTANTS 0x200
#define SP_NEW_SAMPLER 0x400
#define SP_NEW_TEXTURE 0x800
#define SP_NEW_VERTEX 0x1000
#define SP_NEW_VS 0x2000
#define SP_NEW_QUERY 0x4000
struct sp_vertex_shader_state {
struct pipe_shader_state *state;
void *draw_data;
};
struct softpipe_context {
struct pipe_context pipe; /**< base class */
struct softpipe_winsys *winsys; /**< window system interface */

View file

@ -335,6 +335,7 @@ static void shade_destroy(struct quad_stage *qs)
{
struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
tgsi_exec_machine_free_data(&qss->machine);
FREE( qss->inputs );
FREE( qss->outputs );
FREE( qs );

View file

@ -208,16 +208,22 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
struct softpipe_cached_tile *tile
= sp_get_cached_tile(softpipe, softpipe->sbuf_cache, quad->x0, quad->y0);
uint j;
uint face = quad->facing;
if (!softpipe->depth_stencil->stencil[1].enabled) {
/* single-sided stencil test, use front (face=0) state */
face = 0;
}
/* choose front or back face function, operator, etc */
/* XXX we could do these initializations once per primitive */
func = softpipe->depth_stencil->stencil[quad->facing].func;
failOp = softpipe->depth_stencil->stencil[quad->facing].fail_op;
zFailOp = softpipe->depth_stencil->stencil[quad->facing].zfail_op;
zPassOp = softpipe->depth_stencil->stencil[quad->facing].zpass_op;
ref = softpipe->depth_stencil->stencil[quad->facing].ref_value;
wrtMask = softpipe->depth_stencil->stencil[quad->facing].write_mask;
valMask = softpipe->depth_stencil->stencil[quad->facing].value_mask;
func = softpipe->depth_stencil->stencil[face].func;
failOp = softpipe->depth_stencil->stencil[face].fail_op;
zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
ref = softpipe->depth_stencil->stencil[face].ref_value;
wrtMask = softpipe->depth_stencil->stencil[face].write_mask;
valMask = softpipe->depth_stencil->stencil[face].value_mask;
assert(ps); /* shouldn't get here if there's no stencil buffer */

View file

@ -35,13 +35,32 @@
#include "x86/rtasm/x86sse.h"
#define SP_NEW_VIEWPORT 0x1
#define SP_NEW_RASTERIZER 0x2
#define SP_NEW_FS 0x4
#define SP_NEW_BLEND 0x8
#define SP_NEW_CLIP 0x10
#define SP_NEW_SCISSOR 0x20
#define SP_NEW_STIPPLE 0x40
#define SP_NEW_FRAMEBUFFER 0x80
#define SP_NEW_DEPTH_STENCIL_ALPHA 0x100
#define SP_NEW_CONSTANTS 0x200
#define SP_NEW_SAMPLER 0x400
#define SP_NEW_TEXTURE 0x800
#define SP_NEW_VERTEX 0x1000
#define SP_NEW_VS 0x2000
#define SP_NEW_QUERY 0x4000
#ifdef MESA_LLVM
struct gallivm_prog;
#endif
/**
* Softpipe fs state is derived from pipe_shader_state.
*/
/** Subclass of pipe_shader_state */
struct sp_fragment_shader_state {
struct pipe_shader_state shader;
#if defined(__i386__) || defined(__386__)
@ -53,6 +72,14 @@ struct sp_fragment_shader_state {
};
/** Subclass of pipe_shader_state */
struct sp_vertex_shader_state {
struct pipe_shader_state shader;
void *draw_data;
};
void *
softpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);

View file

@ -40,7 +40,7 @@
*/
static void calculate_vertex_layout( struct softpipe_context *softpipe )
{
const struct pipe_shader_state *vs = softpipe->vs->state;
const struct pipe_shader_state *vs = &softpipe->vs->shader;
const struct pipe_shader_state *fs = &softpipe->fs->shader;
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;

View file

@ -42,18 +42,20 @@ void * softpipe_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_fragment_shader_state *state;
/* Decide whether we'll be codegenerating this shader and if so do
* that now.
*/
struct sp_fragment_shader_state *state = MALLOC( sizeof(struct sp_fragment_shader_state) );
state = CALLOC_STRUCT(sp_fragment_shader_state);
if (!state)
return NULL;
state->shader = *templ;
if( softpipe->dump_fs ) {
tgsi_dump(
state->shader.tokens,
0 );
if (softpipe->dump_fs) {
tgsi_dump(state->shader.tokens, 0);
}
#if defined(__i386__) || defined(__386__)
@ -75,6 +77,7 @@ void * softpipe_create_fs_state(struct pipe_context *pipe,
return state;
}
void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@ -84,6 +87,7 @@ void softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
softpipe->dirty |= SP_NEW_FS;
}
void softpipe_delete_fs_state(struct pipe_context *pipe,
void *shader)
{
@ -103,22 +107,16 @@ void * softpipe_create_vs_state(struct pipe_context *pipe,
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_vertex_shader_state *state;
state = MALLOC( sizeof(struct sp_vertex_shader_state) );
state = CALLOC_STRUCT(sp_vertex_shader_state);
if (state == NULL ) {
return NULL;
}
state->state = MALLOC( sizeof(struct pipe_shader_state) );
if (state->state == NULL) {
FREE( state );
return NULL;
}
memcpy( state->state, templ, sizeof(struct pipe_shader_state) );
state->shader = *templ;
state->draw_data = draw_create_vertex_shader(softpipe->draw,
state->state);
&state->shader);
if (state->draw_data == NULL) {
FREE( state->state );
FREE( state );
return NULL;
}
@ -126,6 +124,7 @@ void * softpipe_create_vs_state(struct pipe_context *pipe,
return state;
}
void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@ -137,8 +136,8 @@ void softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
softpipe->dirty |= SP_NEW_VS;
}
void softpipe_delete_vs_state(struct pipe_context *pipe,
void *vs)
void softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
@ -146,12 +145,10 @@ void softpipe_delete_vs_state(struct pipe_context *pipe,
(struct sp_vertex_shader_state *)vs;
draw_delete_vertex_shader(softpipe->draw, state->draw_data);
FREE( state->state );
FREE( state );
}
void softpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
@ -170,5 +167,3 @@ void softpipe_set_constant_buffer(struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_CONSTANTS;
}

View file

@ -126,9 +126,17 @@ void
sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
{
uint pos;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
assert(tc->entries[pos].x < 0);
//assert(tc->entries[pos].x < 0);
}
if (tc->surface) {
pipe_surface_reference(&tc->surface, NULL);
}
if (tc->tex_surf) {
pipe_surface_reference(&tc->tex_surf, NULL);
}
FREE( tc );
}
@ -466,15 +474,12 @@ sp_get_cached_tile_tex(struct pipe_context *pipe,
tc->tex_level != level ||
tc->tex_z != z) {
/* get new surface (view into texture) */
struct pipe_surface *ps;
if (tc->tex_surf && tc->tex_surf->map)
pipe_surface_unmap(tc->tex_surf);
ps = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
pipe_surface_reference(&tc->tex_surf, ps);
pipe_surface_map(ps);
tc->tex_surf = pipe->get_tex_surface(pipe, tc->texture, face, level, z);
pipe_surface_map(tc->tex_surf);
tc->tex_face = face;
tc->tex_level = level;

View file

@ -275,6 +275,22 @@ tgsi_exec_machine_init(
}
void
tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach)
{
if (mach->Instructions) {
FREE(mach->Instructions);
mach->Instructions = NULL;
mach->NumInstructions = 0;
}
if (mach->Declarations) {
FREE(mach->Declarations);
mach->Declarations = NULL;
mach->NumDeclarations = 0;
}
}
static void
micro_abs(
union tgsi_exec_channel *dst,

View file

@ -227,6 +227,11 @@ uint
tgsi_exec_machine_run(
struct tgsi_exec_machine *mach );
void
tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach);
#if defined __cplusplus
} /* extern "C" */
#endif

View file

@ -447,6 +447,10 @@ xmesa_free_buffer(XMesaBuffer buffer)
/* Unreference. If count = zero we'll really delete the buffer */
_mesa_unreference_framebuffer(&fb);
XFreeGC(b->xm_visual->display, b->gc);
free(buffer);
return;
}
/* continue search */

View file

@ -143,6 +143,7 @@ _mesa_delete_program_cache(GLcontext *ctx, struct gl_program_cache *cache)
{
clear_cache(ctx, cache);
_mesa_free(cache->items);
_mesa_free(cache);
}

View file

@ -101,6 +101,7 @@ _mesa_free_program_data(GLcontext *ctx)
if (ctx->VertexProgram.Current->Base.RefCount <= 0)
ctx->Driver.DeleteProgram(ctx, &(ctx->VertexProgram.Current->Base));
}
_mesa_delete_program_cache(ctx, ctx->VertexProgram.Cache);
#endif
#if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
if (ctx->FragmentProgram.Current) {
@ -108,6 +109,7 @@ _mesa_free_program_data(GLcontext *ctx)
if (ctx->FragmentProgram.Current->Base.RefCount <= 0)
ctx->Driver.DeleteProgram(ctx, &(ctx->FragmentProgram.Current->Base));
}
_mesa_delete_program_cache(ctx, ctx->FragmentProgram.Cache);
#endif
/* XXX probably move this stuff */
#if FEATURE_ATI_fragment_shader

View file

@ -51,6 +51,7 @@
#include "st_extensions.h"
#include "st_program.h"
#include "pipe/p_context.h"
#include "pipe/p_winsys.h"
#include "pipe/draw/draw_context.h"
#include "pipe/cso_cache/cso_cache.h"
@ -136,6 +137,9 @@ struct st_context *st_create_context(struct pipe_context *pipe,
static void st_destroy_context_priv( struct st_context *st )
{
struct pipe_winsys *ws = st->pipe->winsys;
uint i;
draw_destroy(st->draw);
st_destroy_atoms( st );
st_destroy_draw( st );
@ -146,6 +150,12 @@ static void st_destroy_context_priv( struct st_context *st )
_mesa_delete_program_cache(st->ctx, st->pixel_xfer.cache);
for (i = 0; i < Elements(st->state.constants); i++) {
if (st->state.constants[i].buffer) {
ws->buffer_reference(ws, &st->state.constants[i].buffer, NULL);
}
}
st->pipe->destroy( st->pipe );
free( st );
}

View file

@ -616,6 +616,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
if (draw->vertex_buffer[i].buffer) {
pipe->winsys->buffer_unmap(pipe->winsys,
draw->vertex_buffer[i].buffer);
winsys->buffer_reference(winsys, &draw->vertex_buffer[i].buffer, NULL);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}

View file

@ -246,6 +246,7 @@ void _vbo_DestroyContext( GLcontext *ctx )
}
vbo_exec_destroy(ctx);
vbo_save_destroy(ctx);
FREE(vbo_context(ctx));
ctx->swtnl_im = NULL;
}

View file

@ -69,6 +69,21 @@ void vbo_save_init( GLcontext *ctx )
void vbo_save_destroy( GLcontext *ctx )
{
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_save_context *save = &vbo->save;
if (save->prim_store) {
if ( --save->prim_store->refcount == 0 ) {
FREE( save->prim_store );
save->prim_store = NULL;
}
if ( --save->vertex_store->refcount == 0 ) {
if (save->vertex_store->bufferobj)
ctx->Driver.DeleteBuffer( ctx, save->vertex_store->bufferobj );
FREE( save->vertex_store );
save->vertex_store = NULL;
}
}
}