gallium: michel's patch to rework texture/sampler binding interface

Bind all the samplers/textures at once rather than piecemeal.
This is easier for drivers to understand.
This commit is contained in:
Keith Whitwell 2008-03-05 10:50:14 +01:00
parent b1922de9f3
commit 4528287e04
25 changed files with 2565 additions and 2453 deletions

View file

@ -78,7 +78,8 @@ struct aaline_stage
void *sampler_cso;
struct pipe_texture *texture;
uint sampler_unit;
uint num_samplers;
uint num_textures;
/*
@ -98,11 +99,10 @@ struct aaline_stage
void (*driver_bind_fs_state)(struct pipe_context *, void *);
void (*driver_delete_fs_state)(struct pipe_context *, void *);
void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *);
void (*driver_set_sampler_texture)(struct pipe_context *,
unsigned sampler,
struct pipe_texture *);
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
void **);
void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
struct pipe_texture **);
struct pipe_context *pipe;
};
@ -607,6 +607,7 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
auto struct aaline_stage *aaline = aaline_stage(stage);
struct draw_context *draw = stage->draw;
struct pipe_context *pipe = aaline->pipe;
uint num = MAX2(aaline->num_textures, aaline->num_samplers);
assert(draw->rasterizer->line_smooth);
@ -624,8 +625,11 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
*/
bind_aaline_fragment_shader(aaline);
aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit, aaline->sampler_cso);
aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit, aaline->texture);
aaline->state.sampler[num] = aaline->sampler_cso;
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);
/* now really draw first line */
stage->line = aaline_line;
@ -647,10 +651,10 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
/* XXX restore original texture, sampler state */
aaline->driver_bind_sampler_state(pipe, aaline->sampler_unit,
aaline->state.sampler[aaline->sampler_unit]);
aaline->driver_set_sampler_texture(pipe, aaline->sampler_unit,
aaline->state.texture[aaline->sampler_unit]);
aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
aaline->state.sampler);
aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
aaline->state.texture);
draw->extra_vp_outputs.slot = 0;
}
@ -745,26 +749,28 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
static void
aaline_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
aaline_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
/* save current */
aaline->state.sampler[unit] = sampler;
memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
aaline->num_samplers = num;
/* pass-through */
aaline->driver_bind_sampler_state(aaline->pipe, unit, sampler);
aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
}
static void
aaline_set_sampler_texture(struct pipe_context *pipe,
unsigned sampler, struct pipe_texture *texture)
aaline_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
{
struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
/* save current */
aaline->state.texture[sampler] = texture;
memcpy(aaline->state.texture, texture, num * sizeof(struct pipe_texture *));
aaline->num_textures = num;
/* pass-through */
aaline->driver_set_sampler_texture(aaline->pipe, sampler, texture);
aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
}
@ -798,14 +804,14 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
aaline->driver_bind_fs_state = pipe->bind_fs_state;
aaline->driver_delete_fs_state = pipe->delete_fs_state;
aaline->driver_bind_sampler_state = pipe->bind_sampler_state;
aaline->driver_set_sampler_texture = pipe->set_sampler_texture;
aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
aaline->driver_set_sampler_textures = pipe->set_sampler_textures;
/* override the driver's functions */
pipe->create_fs_state = aaline_create_fs_state;
pipe->bind_fs_state = aaline_bind_fs_state;
pipe->delete_fs_state = aaline_delete_fs_state;
pipe->bind_sampler_state = aaline_bind_sampler_state;
pipe->set_sampler_texture = aaline_set_sampler_texture;
pipe->bind_sampler_states = aaline_bind_sampler_states;
pipe->set_sampler_textures = aaline_set_sampler_textures;
}

View file

@ -68,7 +68,8 @@ struct pstip_stage
void *sampler_cso;
struct pipe_texture *texture;
uint sampler_unit;
uint num_samplers;
uint num_textures;
/*
* Currently bound state
@ -88,11 +89,10 @@ struct pstip_stage
void (*driver_bind_fs_state)(struct pipe_context *, void *);
void (*driver_delete_fs_state)(struct pipe_context *, void *);
void (*driver_bind_sampler_state)(struct pipe_context *, unsigned, void *);
void (*driver_bind_sampler_states)(struct pipe_context *, unsigned, void **);
void (*driver_set_sampler_texture)(struct pipe_context *,
unsigned sampler,
struct pipe_texture *);
void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
struct pipe_texture **);
void (*driver_set_polygon_stipple)(struct pipe_context *,
const struct pipe_poly_stipple *);
@ -328,8 +328,6 @@ generate_pstip_fs(struct pstip_stage *pstip)
tgsi_dump(pstip_fs.tokens, 0);
#endif
pstip->sampler_unit = transform.maxSampler + 1;
#if 1 /* XXX remove */
if (transform.wincoordInput < 0) {
pstip_fs.input_semantic_name[pstip_fs.num_inputs] = TGSI_SEMANTIC_POSITION;
@ -486,6 +484,7 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
struct pstip_stage *pstip = pstip_stage(stage);
struct draw_context *draw = stage->draw;
struct pipe_context *pipe = pstip->pipe;
uint num = MAX2(pstip->num_textures, pstip->num_samplers);
assert(draw->rasterizer->poly_stipple_enable);
@ -494,8 +493,8 @@ pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
*/
bind_pstip_fragment_shader(pstip);
pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit, pstip->sampler_cso);
pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit, pstip->texture);
pstip->driver_bind_sampler_states(pipe, num + 1, pstip->state.sampler);
pstip->driver_set_sampler_textures(pipe, num + 1, pstip->state.texture);
/* now really draw first line */
stage->tri = passthrough_tri;
@ -517,10 +516,10 @@ pstip_flush(struct draw_stage *stage, unsigned flags)
pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
/* XXX restore original texture, sampler state */
pstip->driver_bind_sampler_state(pipe, pstip->sampler_unit,
pstip->state.sampler[pstip->sampler_unit]);
pstip->driver_set_sampler_texture(pipe, pstip->sampler_unit,
pstip->state.texture[pstip->sampler_unit]);
pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
pstip->state.sampler);
pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
pstip->state.texture);
}
@ -613,26 +612,28 @@ pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
static void
pstip_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
pstip_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
/* save current */
pstip->state.sampler[unit] = sampler;
memcpy(pstip->state.sampler, sampler, num * sizeof(void *));
pstip->num_samplers = num;
/* pass-through */
pstip->driver_bind_sampler_state(pstip->pipe, unit, sampler);
pstip->driver_bind_sampler_states(pstip->pipe, num, sampler);
}
static void
pstip_set_sampler_texture(struct pipe_context *pipe,
unsigned sampler, struct pipe_texture *texture)
pstip_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
{
struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
/* save current */
pstip->state.texture[sampler] = texture;
memcpy(pstip->state.texture, texture, num * sizeof(struct pipe_texture *));
pstip->num_textures = num;
/* pass-through */
pstip->driver_set_sampler_texture(pstip->pipe, sampler, texture);
pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
}
@ -682,8 +683,8 @@ draw_install_pstipple_stage(struct draw_context *draw,
pstip->driver_bind_fs_state = pipe->bind_fs_state;
pstip->driver_delete_fs_state = pipe->delete_fs_state;
pstip->driver_bind_sampler_state = pipe->bind_sampler_state;
pstip->driver_set_sampler_texture = pipe->set_sampler_texture;
pstip->driver_bind_sampler_states = pipe->bind_sampler_states;
pstip->driver_set_sampler_textures = pipe->set_sampler_textures;
pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
/* override the driver's functions */
@ -691,7 +692,7 @@ draw_install_pstipple_stage(struct draw_context *draw,
pipe->bind_fs_state = pstip_bind_fs_state;
pipe->delete_fs_state = pstip_delete_fs_state;
pipe->bind_sampler_state = pstip_bind_sampler_state;
pipe->set_sampler_texture = pstip_set_sampler_texture;
pipe->bind_sampler_states = pstip_bind_sampler_states;
pipe->set_sampler_textures = pstip_set_sampler_textures;
pipe->set_polygon_stipple = pstip_set_polygon_stipple;
}

View file

@ -87,12 +87,15 @@ struct failover_context {
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
void *sw_sampler_state[PIPE_MAX_SAMPLERS];
void *hw_sampler_state[PIPE_MAX_SAMPLERS];
unsigned dirty;
unsigned dirty_sampler;
unsigned dirty_texture;
unsigned dirty_vertex_buffer;
unsigned dirty_vertex_element;
unsigned num_samplers;
unsigned num_textures;
unsigned mode;
struct pipe_context *hw;

View file

@ -28,6 +28,8 @@
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
#include "pipe/p_inlines.h"
#include "fo_context.h"
@ -322,18 +324,27 @@ failover_create_sampler_state(struct pipe_context *pipe,
}
static void
failover_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
failover_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct failover_context *failover = failover_context(pipe);
struct fo_state *state = (struct fo_state*)sampler;
failover->sampler[unit] = state;
uint i;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == failover->num_samplers &&
!memcmp(failover->sampler, sampler, num * sizeof(void *)))
return;
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
failover->sw_sampler_state[i] = i < num ? state[i].sw_state : NULL;
failover->hw_sampler_state[i] = i < num ? state[i].hw_state : NULL;
}
failover->dirty |= FO_NEW_SAMPLER;
failover->dirty_sampler |= (1<<unit);
failover->sw->bind_sampler_state(failover->sw, unit,
state->sw_state);
failover->hw->bind_sampler_state(failover->hw, unit,
state->hw_state);
failover->num_samplers = num;
failover->sw->bind_sampler_states(failover->sw, num,
failover->sw_sampler_state);
failover->hw->bind_sampler_states(failover->hw, num,
failover->hw_sampler_state);
}
static void
@ -351,17 +362,29 @@ failover_delete_sampler_state(struct pipe_context *pipe, void *sampler)
static void
failover_set_sampler_texture(struct pipe_context *pipe,
unsigned unit,
struct pipe_texture *texture)
failover_set_sampler_textures(struct pipe_context *pipe,
unsigned num,
struct pipe_texture **texture)
{
struct failover_context *failover = failover_context(pipe);
uint i;
failover->texture[unit] = texture;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == failover->num_textures &&
!memcmp(failover->texture, texture, num * sizeof(struct pipe_texture *)))
return;
for (i = 0; i < num; i++)
pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
texture[i]);
for (i = num; i < failover->num_textures; i++)
pipe_texture_reference((struct pipe_texture **) &failover->texture[i],
NULL);
failover->dirty |= FO_NEW_TEXTURE;
failover->dirty_texture |= (1<<unit);
failover->sw->set_sampler_texture( failover->sw, unit, texture );
failover->hw->set_sampler_texture( failover->hw, unit, texture );
failover->num_textures = num;
failover->sw->set_sampler_textures( failover->sw, num, texture );
failover->hw->set_sampler_textures( failover->hw, num, texture );
}
@ -429,7 +452,7 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.bind_blend_state = failover_bind_blend_state;
failover->pipe.delete_blend_state = failover_delete_blend_state;
failover->pipe.create_sampler_state = failover_create_sampler_state;
failover->pipe.bind_sampler_state = failover_bind_sampler_state;
failover->pipe.bind_sampler_states = failover_bind_sampler_states;
failover->pipe.delete_sampler_state = failover_delete_sampler_state;
failover->pipe.create_depth_stencil_alpha_state = failover_create_depth_stencil_state;
failover->pipe.bind_depth_stencil_alpha_state = failover_bind_depth_stencil_state;
@ -449,7 +472,7 @@ failover_init_state_functions( struct failover_context *failover )
failover->pipe.set_framebuffer_state = failover_set_framebuffer_state;
failover->pipe.set_polygon_stipple = failover_set_polygon_stipple;
failover->pipe.set_scissor_state = failover_set_scissor_state;
failover->pipe.set_sampler_texture = failover_set_sampler_texture;
failover->pipe.set_sampler_textures = failover_set_sampler_textures;
failover->pipe.set_viewport_state = failover_set_viewport_state;
failover->pipe.set_vertex_buffer = failover_set_vertex_buffer;
failover->pipe.set_vertex_element = failover_set_vertex_element;

View file

@ -94,21 +94,13 @@ failover_state_emit( struct failover_context *failover )
failover->sw->set_viewport_state( failover->sw, &failover->viewport );
if (failover->dirty & FO_NEW_SAMPLER) {
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
if (failover->dirty_sampler & (1<<i)) {
failover->sw->bind_sampler_state( failover->sw, i,
failover->sampler[i]->sw_state );
}
}
failover->sw->bind_sampler_states( failover->sw, failover->num_samplers,
failover->sw_sampler_state );
}
if (failover->dirty & FO_NEW_TEXTURE) {
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
if (failover->dirty_texture & (1<<i)) {
failover->sw->set_sampler_texture( failover->sw, i,
failover->texture[i] );
}
}
failover->sw->set_sampler_textures( failover->sw, failover->num_textures,
failover->texture );
}
if (failover->dirty & FO_NEW_VERTEX_BUFFER) {
@ -132,6 +124,4 @@ failover_state_emit( struct failover_context *failover )
failover->dirty = 0;
failover->dirty_vertex_element = 0;
failover->dirty_vertex_buffer = 0;
failover->dirty_texture = 0;
failover->dirty_sampler = 0;
}

View file

@ -1,336 +1,339 @@
/**************************************************************************
*
* Copyright 2003 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 I915_CONTEXT_H
#define I915_CONTEXT_H
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "draw/draw_vertex.h"
#include "tgsi/util/tgsi_scan.h"
#define I915_TEX_UNITS 8
#define I915_DYNAMIC_MODES4 0
#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */
#define I915_DYNAMIC_DEPTHSCALE_1 2
#define I915_DYNAMIC_IAB 3
#define I915_DYNAMIC_BC_0 4 /* just the header */
#define I915_DYNAMIC_BC_1 5
#define I915_DYNAMIC_BFO_0 6
#define I915_DYNAMIC_BFO_1 7
#define I915_DYNAMIC_STP_0 8
#define I915_DYNAMIC_STP_1 9
#define I915_DYNAMIC_SC_ENA_0 10
#define I915_DYNAMIC_SC_RECT_0 11
#define I915_DYNAMIC_SC_RECT_1 12
#define I915_DYNAMIC_SC_RECT_2 13
#define I915_MAX_DYNAMIC 14
#define I915_IMMEDIATE_S0 0
#define I915_IMMEDIATE_S1 1
#define I915_IMMEDIATE_S2 2
#define I915_IMMEDIATE_S3 3
#define I915_IMMEDIATE_S4 4
#define I915_IMMEDIATE_S5 5
#define I915_IMMEDIATE_S6 6
#define I915_IMMEDIATE_S7 7
#define I915_MAX_IMMEDIATE 8
/* These must mach the order of LI0_STATE_* bits, as they will be used
* to generate hardware packets:
*/
#define I915_CACHE_STATIC 0
#define I915_CACHE_DYNAMIC 1 /* handled specially */
#define I915_CACHE_SAMPLER 2
#define I915_CACHE_MAP 3
#define I915_CACHE_PROGRAM 4
#define I915_CACHE_CONSTANTS 5
#define I915_MAX_CACHE 6
#define I915_MAX_CONSTANT 32
/** See constant_flags[] below */
#define I915_CONSTFLAG_USER 0x1f
/**
* Subclass of pipe_shader_state
*/
struct i915_fragment_shader
{
struct pipe_shader_state state;
struct tgsi_shader_info info;
uint *program;
uint program_len;
/**
* constants introduced during translation.
* These are placed at the end of the constant buffer and grow toward
* the beginning (eg: slot 31, 30 29, ...)
* User-provided constants start at 0.
* This allows both types of constants to co-exist (until there's too many)
* and doesn't require regenerating/changing the fragment program to
* shuffle constants around.
*/
uint num_constants;
float constants[I915_MAX_CONSTANT][4];
/**
* Status of each constant
* if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding
* slot of the user's constant buffer. (set by pipe->set_constant_buffer())
* Else, the bitmask indicates which components are occupied by immediates.
*/
ubyte constant_flags[I915_MAX_CONSTANT];
};
struct i915_cache_context;
/* Use to calculate differences between state emitted to hardware and
* current driver-calculated state.
*/
struct i915_state
{
unsigned immediate[I915_MAX_IMMEDIATE];
unsigned dynamic[I915_MAX_DYNAMIC];
float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
/** number of constants passed in through a constant buffer */
uint num_user_constants[PIPE_SHADER_TYPES];
/* texture sampler state */
unsigned sampler[I915_TEX_UNITS][3];
unsigned sampler_enable_flags;
unsigned sampler_enable_nr;
/* texture image buffers */
unsigned texbuffer[I915_TEX_UNITS][2];
/** Describes the current hardware vertex layout */
struct vertex_info vertex_info;
unsigned id; /* track lost context events */
};
struct i915_blend_state {
unsigned iab;
unsigned modes4;
unsigned LIS5;
unsigned LIS6;
};
struct i915_depth_stencil_state {
unsigned stencil_modes4;
unsigned bfo[2];
unsigned stencil_LIS5;
unsigned depth_LIS6;
};
struct i915_rasterizer_state {
int light_twoside : 1;
unsigned st;
enum interp_mode color_interp;
unsigned LIS4;
unsigned LIS7;
unsigned sc[1];
const struct pipe_rasterizer_state *templ;
union { float f; unsigned u; } ds[2];
};
struct i915_sampler_state {
unsigned state[3];
const struct pipe_sampler_state *templ;
};
struct i915_texture {
struct pipe_texture base;
/* Derived from the above:
*/
unsigned pitch;
unsigned depth_pitch; /* per-image on i945? */
unsigned total_height;
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
/* Explicitly store the offset of each image for each cube face or
* depth value. Pretty much have to accept that hardware formats
* are going to be so diverse that there is no unified way to
* compute the offsets of depth/cube images within a mipmap level,
* so have to store them as a lookup table:
*/
unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
/* Includes image offset tables:
*/
unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
struct pipe_buffer *buffer;
};
struct i915_context
{
struct pipe_context pipe;
struct i915_winsys *winsys;
struct draw_context *draw;
/* The most recent drawing state as set by the driver:
*/
const struct i915_blend_state *blend;
const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct i915_depth_stencil_state *depth_stencil;
const struct i915_rasterizer_state *rasterizer;
struct i915_fragment_shader *fs;
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct i915_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
unsigned dirty;
unsigned *batch_start;
/** Vertex buffer */
struct pipe_buffer *vbo;
struct i915_state current;
unsigned hardware_dirty;
unsigned debug;
};
/* A flag for each state_tracker state object:
*/
#define I915_NEW_VIEWPORT 0x1
#define I915_NEW_RASTERIZER 0x2
#define I915_NEW_FS 0x4
#define I915_NEW_BLEND 0x8
#define I915_NEW_CLIP 0x10
#define I915_NEW_SCISSOR 0x20
#define I915_NEW_STIPPLE 0x40
#define I915_NEW_FRAMEBUFFER 0x80
#define I915_NEW_ALPHA_TEST 0x100
#define I915_NEW_DEPTH_STENCIL 0x200
#define I915_NEW_SAMPLER 0x400
#define I915_NEW_TEXTURE 0x800
#define I915_NEW_CONSTANTS 0x1000
#define I915_NEW_VBO 0x2000
#define I915_NEW_VS 0x4000
/* Driver's internally generated state flags:
*/
#define I915_NEW_VERTEX_FORMAT 0x10000
/* Dirty flags for hardware emit
*/
#define I915_HW_STATIC (1<<I915_CACHE_STATIC)
#define I915_HW_DYNAMIC (1<<I915_CACHE_DYNAMIC)
#define I915_HW_SAMPLER (1<<I915_CACHE_SAMPLER)
#define I915_HW_MAP (1<<I915_CACHE_MAP)
#define I915_HW_PROGRAM (1<<I915_CACHE_PROGRAM)
#define I915_HW_CONSTANTS (1<<I915_CACHE_CONSTANTS)
#define I915_HW_IMMEDIATE (1<<(I915_MAX_CACHE+0))
#define I915_HW_INVARIENT (1<<(I915_MAX_CACHE+1))
/***********************************************************************
* i915_prim_emit.c:
*/
struct draw_stage *i915_draw_render_stage( struct i915_context *i915 );
/***********************************************************************
* i915_prim_vbuf.c:
*/
struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );
/***********************************************************************
* i915_state_emit.c:
*/
void i915_emit_hardware_state(struct i915_context *i915 );
/***********************************************************************
* i915_clear.c:
*/
void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue);
/***********************************************************************
* i915_surface.c:
*/
void i915_init_surface_functions( struct i915_context *i915 );
void i915_init_state_functions( struct i915_context *i915 );
void i915_init_flush_functions( struct i915_context *i915 );
void i915_init_string_functions( struct i915_context *i915 );
/***********************************************************************
* Inline conversion functions. These are better-typed than the
* macros used previously:
*/
static INLINE struct i915_context *
i915_context( struct pipe_context *pipe )
{
return (struct i915_context *)pipe;
}
#endif
/**************************************************************************
*
* Copyright 2003 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 I915_CONTEXT_H
#define I915_CONTEXT_H
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
#include "draw/draw_vertex.h"
#include "tgsi/util/tgsi_scan.h"
#define I915_TEX_UNITS 8
#define I915_DYNAMIC_MODES4 0
#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */
#define I915_DYNAMIC_DEPTHSCALE_1 2
#define I915_DYNAMIC_IAB 3
#define I915_DYNAMIC_BC_0 4 /* just the header */
#define I915_DYNAMIC_BC_1 5
#define I915_DYNAMIC_BFO_0 6
#define I915_DYNAMIC_BFO_1 7
#define I915_DYNAMIC_STP_0 8
#define I915_DYNAMIC_STP_1 9
#define I915_DYNAMIC_SC_ENA_0 10
#define I915_DYNAMIC_SC_RECT_0 11
#define I915_DYNAMIC_SC_RECT_1 12
#define I915_DYNAMIC_SC_RECT_2 13
#define I915_MAX_DYNAMIC 14
#define I915_IMMEDIATE_S0 0
#define I915_IMMEDIATE_S1 1
#define I915_IMMEDIATE_S2 2
#define I915_IMMEDIATE_S3 3
#define I915_IMMEDIATE_S4 4
#define I915_IMMEDIATE_S5 5
#define I915_IMMEDIATE_S6 6
#define I915_IMMEDIATE_S7 7
#define I915_MAX_IMMEDIATE 8
/* These must mach the order of LI0_STATE_* bits, as they will be used
* to generate hardware packets:
*/
#define I915_CACHE_STATIC 0
#define I915_CACHE_DYNAMIC 1 /* handled specially */
#define I915_CACHE_SAMPLER 2
#define I915_CACHE_MAP 3
#define I915_CACHE_PROGRAM 4
#define I915_CACHE_CONSTANTS 5
#define I915_MAX_CACHE 6
#define I915_MAX_CONSTANT 32
/** See constant_flags[] below */
#define I915_CONSTFLAG_USER 0x1f
/**
* Subclass of pipe_shader_state
*/
struct i915_fragment_shader
{
struct pipe_shader_state state;
struct tgsi_shader_info info;
uint *program;
uint program_len;
/**
* constants introduced during translation.
* These are placed at the end of the constant buffer and grow toward
* the beginning (eg: slot 31, 30 29, ...)
* User-provided constants start at 0.
* This allows both types of constants to co-exist (until there's too many)
* and doesn't require regenerating/changing the fragment program to
* shuffle constants around.
*/
uint num_constants;
float constants[I915_MAX_CONSTANT][4];
/**
* Status of each constant
* if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding
* slot of the user's constant buffer. (set by pipe->set_constant_buffer())
* Else, the bitmask indicates which components are occupied by immediates.
*/
ubyte constant_flags[I915_MAX_CONSTANT];
};
struct i915_cache_context;
/* Use to calculate differences between state emitted to hardware and
* current driver-calculated state.
*/
struct i915_state
{
unsigned immediate[I915_MAX_IMMEDIATE];
unsigned dynamic[I915_MAX_DYNAMIC];
float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
/** number of constants passed in through a constant buffer */
uint num_user_constants[PIPE_SHADER_TYPES];
/* texture sampler state */
unsigned sampler[I915_TEX_UNITS][3];
unsigned sampler_enable_flags;
unsigned sampler_enable_nr;
/* texture image buffers */
unsigned texbuffer[I915_TEX_UNITS][2];
/** Describes the current hardware vertex layout */
struct vertex_info vertex_info;
unsigned id; /* track lost context events */
};
struct i915_blend_state {
unsigned iab;
unsigned modes4;
unsigned LIS5;
unsigned LIS6;
};
struct i915_depth_stencil_state {
unsigned stencil_modes4;
unsigned bfo[2];
unsigned stencil_LIS5;
unsigned depth_LIS6;
};
struct i915_rasterizer_state {
int light_twoside : 1;
unsigned st;
enum interp_mode color_interp;
unsigned LIS4;
unsigned LIS7;
unsigned sc[1];
const struct pipe_rasterizer_state *templ;
union { float f; unsigned u; } ds[2];
};
struct i915_sampler_state {
unsigned state[3];
const struct pipe_sampler_state *templ;
};
struct i915_texture {
struct pipe_texture base;
/* Derived from the above:
*/
unsigned pitch;
unsigned depth_pitch; /* per-image on i945? */
unsigned total_height;
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
/* Explicitly store the offset of each image for each cube face or
* depth value. Pretty much have to accept that hardware formats
* are going to be so diverse that there is no unified way to
* compute the offsets of depth/cube images within a mipmap level,
* so have to store them as a lookup table:
*/
unsigned *image_offset[PIPE_MAX_TEXTURE_LEVELS]; /**< array [depth] of offsets */
/* Includes image offset tables:
*/
unsigned level_offset[PIPE_MAX_TEXTURE_LEVELS];
/* The data is held here:
*/
struct pipe_buffer *buffer;
};
struct i915_context
{
struct pipe_context pipe;
struct i915_winsys *winsys;
struct draw_context *draw;
/* The most recent drawing state as set by the driver:
*/
const struct i915_blend_state *blend;
const struct i915_sampler_state *sampler[PIPE_MAX_SAMPLERS];
const struct i915_depth_stencil_state *depth_stencil;
const struct i915_rasterizer_state *rasterizer;
struct i915_fragment_shader *fs;
struct pipe_blend_color blend_color;
struct pipe_clip_state clip;
struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct i915_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_ATTRIB_MAX];
unsigned dirty;
unsigned num_samplers;
unsigned num_textures;
unsigned *batch_start;
/** Vertex buffer */
struct pipe_buffer *vbo;
struct i915_state current;
unsigned hardware_dirty;
unsigned debug;
};
/* A flag for each state_tracker state object:
*/
#define I915_NEW_VIEWPORT 0x1
#define I915_NEW_RASTERIZER 0x2
#define I915_NEW_FS 0x4
#define I915_NEW_BLEND 0x8
#define I915_NEW_CLIP 0x10
#define I915_NEW_SCISSOR 0x20
#define I915_NEW_STIPPLE 0x40
#define I915_NEW_FRAMEBUFFER 0x80
#define I915_NEW_ALPHA_TEST 0x100
#define I915_NEW_DEPTH_STENCIL 0x200
#define I915_NEW_SAMPLER 0x400
#define I915_NEW_TEXTURE 0x800
#define I915_NEW_CONSTANTS 0x1000
#define I915_NEW_VBO 0x2000
#define I915_NEW_VS 0x4000
/* Driver's internally generated state flags:
*/
#define I915_NEW_VERTEX_FORMAT 0x10000
/* Dirty flags for hardware emit
*/
#define I915_HW_STATIC (1<<I915_CACHE_STATIC)
#define I915_HW_DYNAMIC (1<<I915_CACHE_DYNAMIC)
#define I915_HW_SAMPLER (1<<I915_CACHE_SAMPLER)
#define I915_HW_MAP (1<<I915_CACHE_MAP)
#define I915_HW_PROGRAM (1<<I915_CACHE_PROGRAM)
#define I915_HW_CONSTANTS (1<<I915_CACHE_CONSTANTS)
#define I915_HW_IMMEDIATE (1<<(I915_MAX_CACHE+0))
#define I915_HW_INVARIENT (1<<(I915_MAX_CACHE+1))
/***********************************************************************
* i915_prim_emit.c:
*/
struct draw_stage *i915_draw_render_stage( struct i915_context *i915 );
/***********************************************************************
* i915_prim_vbuf.c:
*/
struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 );
/***********************************************************************
* i915_state_emit.c:
*/
void i915_emit_hardware_state(struct i915_context *i915 );
/***********************************************************************
* i915_clear.c:
*/
void i915_clear(struct pipe_context *pipe, struct pipe_surface *ps,
unsigned clearValue);
/***********************************************************************
* i915_surface.c:
*/
void i915_init_surface_functions( struct i915_context *i915 );
void i915_init_state_functions( struct i915_context *i915 );
void i915_init_flush_functions( struct i915_context *i915 );
void i915_init_string_functions( struct i915_context *i915 );
/***********************************************************************
* Inline conversion functions. These are better-typed than the
* macros used previously:
*/
static INLINE struct i915_context *
i915_context( struct pipe_context *pipe )
{
return (struct i915_context *)pipe;
}
#endif

View file

@ -269,13 +269,22 @@ i915_create_sampler_state(struct pipe_context *pipe,
return cso;
}
static void i915_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
static void i915_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct i915_context *i915 = i915_context(pipe);
assert(unit < PIPE_MAX_SAMPLERS);
i915->sampler[unit] = (const struct i915_sampler_state*)sampler;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == i915->num_samplers &&
!memcmp(i915->sampler, sampler, num * sizeof(void *)))
return;
memcpy(i915->sampler, sampler, num * sizeof(void *));
memset(&i915->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) * sizeof(void *));
i915->num_samplers = num;
i915->dirty |= I915_NEW_SAMPLER;
}
@ -526,14 +535,29 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
}
static void i915_set_sampler_texture(struct pipe_context *pipe,
unsigned sampler,
struct pipe_texture *texture)
static void i915_set_sampler_textures(struct pipe_context *pipe,
unsigned num,
struct pipe_texture **texture)
{
struct i915_context *i915 = i915_context(pipe);
uint i;
pipe_texture_reference((struct pipe_texture **) &i915->texture[sampler],
texture);
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == i915->num_textures &&
!memcmp(i915->texture, texture, num * sizeof(struct pipe_texture *)))
return;
for (i = 0; i < num; i++)
pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
texture[i]);
for (i = num; i < i915->num_textures; i++)
pipe_texture_reference((struct pipe_texture **) &i915->texture[i],
NULL);
i915->num_textures = num;
i915->dirty |= I915_NEW_TEXTURE;
}
@ -691,7 +715,7 @@ i915_init_state_functions( struct i915_context *i915 )
i915->pipe.delete_blend_state = i915_delete_blend_state;
i915->pipe.create_sampler_state = i915_create_sampler_state;
i915->pipe.bind_sampler_state = i915_bind_sampler_state;
i915->pipe.bind_sampler_states = i915_bind_sampler_states;
i915->pipe.delete_sampler_state = i915_delete_sampler_state;
i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
@ -715,7 +739,7 @@ i915_init_state_functions( struct i915_context *i915 )
i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
i915->pipe.set_scissor_state = i915_set_scissor_state;
i915->pipe.set_sampler_texture = i915_set_sampler_texture;
i915->pipe.set_sampler_textures = i915_set_sampler_textures;
i915->pipe.set_viewport_state = i915_set_viewport_state;
i915->pipe.set_vertex_buffer = i915_set_vertex_buffer;
i915->pipe.set_vertex_element = i915_set_vertex_element;

View file

@ -267,12 +267,6 @@ i915_emit_hardware_state(struct i915_context *i915 )
/* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */
if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER))
{
/* XXX: we were refering to sampler state
* (current.sampler_enable_nr) below, but only checking
* I915_HW_MAP above. Should probably calculate the enabled
* flags separately - but there will be further rework of
* state so perhaps not necessary yet.
*/
const uint nr = i915->current.sampler_enable_nr;
if (nr) {
const uint enabled = i915->current.sampler_enable_flags;

View file

@ -106,7 +106,8 @@ void i915_update_samplers( struct i915_context *i915 )
i915->current.sampler_enable_nr = 0;
i915->current.sampler_enable_flags = 0x0;
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
if (i915->texture[unit]) {
@ -219,7 +220,8 @@ i915_update_textures(struct i915_context *i915)
{
uint unit;
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
for (unit = 0; unit < i915->num_textures && unit < i915->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
/* could also examine the fragment program? */
if (i915->texture[unit]) {

File diff suppressed because it is too large Load diff

View file

@ -1,434 +1,462 @@
/**************************************************************************
*
* 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: Zack Rusin <zack@tungstengraphics.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_dump.h"
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_state.h"
#include "brw_draw.h"
#define DUP( TYPE, VAL ) \
do { \
struct TYPE *x = malloc(sizeof(*x)); \
memcpy(x, VAL, sizeof(*x) ); \
return x; \
} while (0)
/************************************************************************
* Blend
*/
static void *
brw_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
DUP( pipe_blend_state, blend );
}
static void brw_bind_blend_state(struct pipe_context *pipe,
void *blend)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Blend = (struct pipe_blend_state*)blend;
brw->state.dirty.brw |= BRW_NEW_BLEND;
}
static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
{
free(blend);
}
static void brw_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.BlendColor = *blend_color;
brw->state.dirty.brw |= BRW_NEW_BLEND;
}
/************************************************************************
* Sampler
*/
static void *
brw_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
DUP( pipe_sampler_state, sampler );
}
static void brw_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Samplers[unit] = sampler;
brw->state.dirty.brw |= BRW_NEW_SAMPLER;
}
static void brw_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
free(sampler);
}
/************************************************************************
* Depth stencil
*/
static void *
brw_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *depth_stencil)
{
DUP( pipe_depth_stencil_alpha_state, depth_stencil );
}
static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
}
static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
free(depth_stencil);
}
/************************************************************************
* Scissor
*/
static void brw_set_scissor_state( struct pipe_context *pipe,
const struct pipe_scissor_state *scissor )
{
struct brw_context *brw = brw_context(pipe);
memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
brw->state.dirty.brw |= BRW_NEW_SCISSOR;
}
/************************************************************************
* Stipple
*/
static void brw_set_polygon_stipple( struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple )
{
}
/************************************************************************
* Fragment shader
*/
static void * brw_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *shader)
{
struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_fp->program = *shader;
brw_fp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_fp->info);
#if 0
brw_shader_info(shader->tokens,
&brw_fp->info2);
#endif
tgsi_dump(shader->tokens, 0);
return (void *)brw_fp;
}
static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
brw->state.dirty.brw |= BRW_NEW_FS;
}
static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
{
FREE(shader);
}
/************************************************************************
* Vertex shader and other TNL state
*/
static void *brw_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *shader)
{
struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_vp->program = *shader;
brw_vp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_vp->info);
#if 0
brw_shader_info(shader->tokens,
&brw_vp->info2);
#endif
tgsi_dump(shader->tokens, 0);
return (void *)brw_vp;
}
static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
brw->state.dirty.brw |= BRW_NEW_VS;
debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
}
static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
{
FREE(shader);
}
static void brw_set_clip_state( struct pipe_context *pipe,
const struct pipe_clip_state *clip )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Clip = *clip;
}
static void brw_set_viewport_state( struct pipe_context *pipe,
const struct pipe_viewport_state *viewport )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Viewport = *viewport; /* struct copy */
brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
/* pass the viewport info to the draw module */
//draw_set_viewport_state(brw->draw, viewport);
}
static void brw_set_vertex_buffer( struct pipe_context *pipe,
unsigned index,
const struct pipe_vertex_buffer *buffer )
{
struct brw_context *brw = brw_context(pipe);
brw->vb.vbo_array[index] = buffer;
}
static void brw_set_vertex_element(struct pipe_context *pipe,
unsigned index,
const struct pipe_vertex_element *element)
{
/* flush ? */
struct brw_context *brw = brw_context(pipe);
assert(index < PIPE_ATTRIB_MAX);
struct brw_vertex_element_state el;
memset(&el, 0, sizeof(el));
el.ve0.src_offset = element->src_offset;
el.ve0.src_format = brw_translate_surface_format(element->src_format);
el.ve0.valid = 1;
el.ve0.vertex_buffer_index = element->vertex_buffer_index;
el.ve1.dst_offset = index * 4;
el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
switch (element->nr_components) {
case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
break;
}
brw->vb.inputs[index] = el;
}
/************************************************************************
* Constant buffers
*/
static void brw_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
{
struct brw_context *brw = brw_context(pipe);
assert(buf == 0 || index == 0);
brw->attribs.Constants[shader] = buf;
brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
}
/************************************************************************
* Texture surfaces
*/
static void brw_set_sampler_texture(struct pipe_context *pipe,
unsigned unit,
struct pipe_texture *texture)
{
struct brw_context *brw = brw_context(pipe);
pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[unit],
texture);
brw->state.dirty.brw |= BRW_NEW_TEXTURE;
}
/************************************************************************
* Render targets, etc
*/
static void brw_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.FrameBuffer = *fb; /* struct copy */
brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
}
/************************************************************************
* Rasterizer state
*/
static void *
brw_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rasterizer)
{
DUP(pipe_rasterizer_state, rasterizer);
}
static void brw_bind_rasterizer_state( struct pipe_context *pipe,
void *setup )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
/* Also pass-through to draw module:
*/
//draw_set_rasterizer_state(brw->draw, setup);
brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
}
static void brw_delete_rasterizer_state(struct pipe_context *pipe,
void *setup)
{
free(setup);
}
void
brw_init_state_functions( struct brw_context *brw )
{
brw->pipe.create_blend_state = brw_create_blend_state;
brw->pipe.bind_blend_state = brw_bind_blend_state;
brw->pipe.delete_blend_state = brw_delete_blend_state;
brw->pipe.create_sampler_state = brw_create_sampler_state;
brw->pipe.bind_sampler_state = brw_bind_sampler_state;
brw->pipe.delete_sampler_state = brw_delete_sampler_state;
brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
brw->pipe.create_fs_state = brw_create_fs_state;
brw->pipe.bind_fs_state = brw_bind_fs_state;
brw->pipe.delete_fs_state = brw_delete_fs_state;
brw->pipe.create_vs_state = brw_create_vs_state;
brw->pipe.bind_vs_state = brw_bind_vs_state;
brw->pipe.delete_vs_state = brw_delete_vs_state;
brw->pipe.set_blend_color = brw_set_blend_color;
brw->pipe.set_clip_state = brw_set_clip_state;
brw->pipe.set_constant_buffer = brw_set_constant_buffer;
brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
// brw->pipe.set_feedback_state = brw_set_feedback_state;
// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
brw->pipe.set_scissor_state = brw_set_scissor_state;
brw->pipe.set_sampler_texture = brw_set_sampler_texture;
brw->pipe.set_viewport_state = brw_set_viewport_state;
brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
brw->pipe.set_vertex_element = brw_set_vertex_element;
}
/**************************************************************************
*
* 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: Zack Rusin <zack@tungstengraphics.com>
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_dump.h"
#include "brw_context.h"
#include "brw_defines.h"
#include "brw_state.h"
#include "brw_draw.h"
#define DUP( TYPE, VAL ) \
do { \
struct TYPE *x = malloc(sizeof(*x)); \
memcpy(x, VAL, sizeof(*x) ); \
return x; \
} while (0)
/************************************************************************
* Blend
*/
static void *
brw_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
DUP( pipe_blend_state, blend );
}
static void brw_bind_blend_state(struct pipe_context *pipe,
void *blend)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Blend = (struct pipe_blend_state*)blend;
brw->state.dirty.brw |= BRW_NEW_BLEND;
}
static void brw_delete_blend_state(struct pipe_context *pipe, void *blend)
{
free(blend);
}
static void brw_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.BlendColor = *blend_color;
brw->state.dirty.brw |= BRW_NEW_BLEND;
}
/************************************************************************
* Sampler
*/
static void *
brw_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
DUP( pipe_sampler_state, sampler );
}
static void brw_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct brw_context *brw = brw_context(pipe);
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == brw->num_samplers &&
!memcmp(brw->attribs.Samplers, sampler, num * sizeof(void *)))
return;
memcpy(brw->attribs.Samplers, sampler, num * sizeof(void *));
memset(&brw->attribs.Samplers[num], 0, (PIPE_MAX_SAMPLERS - num) *
sizeof(void *));
brw->num_samplers = num;
brw->state.dirty.brw |= BRW_NEW_SAMPLER;
}
static void brw_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
free(sampler);
}
/************************************************************************
* Depth stencil
*/
static void *
brw_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *depth_stencil)
{
DUP( pipe_depth_stencil_alpha_state, depth_stencil );
}
static void brw_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.DepthStencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
brw->state.dirty.brw |= BRW_NEW_DEPTH_STENCIL;
}
static void brw_delete_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
free(depth_stencil);
}
/************************************************************************
* Scissor
*/
static void brw_set_scissor_state( struct pipe_context *pipe,
const struct pipe_scissor_state *scissor )
{
struct brw_context *brw = brw_context(pipe);
memcpy( &brw->attribs.Scissor, scissor, sizeof(*scissor) );
brw->state.dirty.brw |= BRW_NEW_SCISSOR;
}
/************************************************************************
* Stipple
*/
static void brw_set_polygon_stipple( struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple )
{
}
/************************************************************************
* Fragment shader
*/
static void * brw_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *shader)
{
struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_fp->program = *shader;
brw_fp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_fp->info);
#if 0
brw_shader_info(shader->tokens,
&brw_fp->info2);
#endif
tgsi_dump(shader->tokens, 0);
return (void *)brw_fp;
}
static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.FragmentProgram = (struct brw_fragment_program *)shader;
brw->state.dirty.brw |= BRW_NEW_FS;
}
static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
{
FREE(shader);
}
/************************************************************************
* Vertex shader and other TNL state
*/
static void *brw_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *shader)
{
struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
/* XXX: Do I have to duplicate the tokens as well??
*/
brw_vp->program = *shader;
brw_vp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_vp->info);
#if 0
brw_shader_info(shader->tokens,
&brw_vp->info2);
#endif
tgsi_dump(shader->tokens, 0);
return (void *)brw_vp;
}
static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.VertexProgram = (struct brw_vertex_program *)vs;
brw->state.dirty.brw |= BRW_NEW_VS;
debug_printf("YYYYYYYYYYYYY BINDING VERTEX SHADER\n");
}
static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
{
FREE(shader);
}
static void brw_set_clip_state( struct pipe_context *pipe,
const struct pipe_clip_state *clip )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Clip = *clip;
}
static void brw_set_viewport_state( struct pipe_context *pipe,
const struct pipe_viewport_state *viewport )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Viewport = *viewport; /* struct copy */
brw->state.dirty.brw |= BRW_NEW_VIEWPORT;
/* pass the viewport info to the draw module */
//draw_set_viewport_state(brw->draw, viewport);
}
static void brw_set_vertex_buffer( struct pipe_context *pipe,
unsigned index,
const struct pipe_vertex_buffer *buffer )
{
struct brw_context *brw = brw_context(pipe);
brw->vb.vbo_array[index] = buffer;
}
static void brw_set_vertex_element(struct pipe_context *pipe,
unsigned index,
const struct pipe_vertex_element *element)
{
/* flush ? */
struct brw_context *brw = brw_context(pipe);
assert(index < PIPE_ATTRIB_MAX);
struct brw_vertex_element_state el;
memset(&el, 0, sizeof(el));
el.ve0.src_offset = element->src_offset;
el.ve0.src_format = brw_translate_surface_format(element->src_format);
el.ve0.valid = 1;
el.ve0.vertex_buffer_index = element->vertex_buffer_index;
el.ve1.dst_offset = index * 4;
el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_SRC;
el.ve1.vfcomponent0 = BRW_VFCOMPONENT_STORE_SRC;
switch (element->nr_components) {
case 1: el.ve1.vfcomponent1 = BRW_VFCOMPONENT_STORE_0;
case 2: el.ve1.vfcomponent2 = BRW_VFCOMPONENT_STORE_0;
case 3: el.ve1.vfcomponent3 = BRW_VFCOMPONENT_STORE_1_FLT;
break;
}
brw->vb.inputs[index] = el;
}
/************************************************************************
* Constant buffers
*/
static void brw_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
const struct pipe_constant_buffer *buf)
{
struct brw_context *brw = brw_context(pipe);
assert(buf == 0 || index == 0);
brw->attribs.Constants[shader] = buf;
brw->state.dirty.brw |= BRW_NEW_CONSTANTS;
}
/************************************************************************
* Texture surfaces
*/
static void brw_set_sampler_textures(struct pipe_context *pipe,
unsigned num,
struct pipe_texture **texture)
{
struct brw_context *brw = brw_context(pipe);
uint i;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == brw->num_textures &&
!memcmp(brw->attribs.Texture, texture, num *
sizeof(struct pipe_texture *)))
return;
for (i = 0; i < num; i++)
pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
texture[i]);
for (i = num; i < brw->num_textures; i++)
pipe_texture_reference((struct pipe_texture **) &brw->attribs.Texture[i],
NULL);
brw->num_textures = num;
brw->state.dirty.brw |= BRW_NEW_TEXTURE;
}
/************************************************************************
* Render targets, etc
*/
static void brw_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.FrameBuffer = *fb; /* struct copy */
brw->state.dirty.brw |= BRW_NEW_FRAMEBUFFER;
}
/************************************************************************
* Rasterizer state
*/
static void *
brw_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rasterizer)
{
DUP(pipe_rasterizer_state, rasterizer);
}
static void brw_bind_rasterizer_state( struct pipe_context *pipe,
void *setup )
{
struct brw_context *brw = brw_context(pipe);
brw->attribs.Raster = (struct pipe_rasterizer_state *)setup;
/* Also pass-through to draw module:
*/
//draw_set_rasterizer_state(brw->draw, setup);
brw->state.dirty.brw |= BRW_NEW_RASTERIZER;
}
static void brw_delete_rasterizer_state(struct pipe_context *pipe,
void *setup)
{
free(setup);
}
void
brw_init_state_functions( struct brw_context *brw )
{
brw->pipe.create_blend_state = brw_create_blend_state;
brw->pipe.bind_blend_state = brw_bind_blend_state;
brw->pipe.delete_blend_state = brw_delete_blend_state;
brw->pipe.create_sampler_state = brw_create_sampler_state;
brw->pipe.bind_sampler_states = brw_bind_sampler_states;
brw->pipe.delete_sampler_state = brw_delete_sampler_state;
brw->pipe.create_depth_stencil_alpha_state = brw_create_depth_stencil_state;
brw->pipe.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state;
brw->pipe.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state;
brw->pipe.create_rasterizer_state = brw_create_rasterizer_state;
brw->pipe.bind_rasterizer_state = brw_bind_rasterizer_state;
brw->pipe.delete_rasterizer_state = brw_delete_rasterizer_state;
brw->pipe.create_fs_state = brw_create_fs_state;
brw->pipe.bind_fs_state = brw_bind_fs_state;
brw->pipe.delete_fs_state = brw_delete_fs_state;
brw->pipe.create_vs_state = brw_create_vs_state;
brw->pipe.bind_vs_state = brw_bind_vs_state;
brw->pipe.delete_vs_state = brw_delete_vs_state;
brw->pipe.set_blend_color = brw_set_blend_color;
brw->pipe.set_clip_state = brw_set_clip_state;
brw->pipe.set_constant_buffer = brw_set_constant_buffer;
brw->pipe.set_framebuffer_state = brw_set_framebuffer_state;
// brw->pipe.set_feedback_state = brw_set_feedback_state;
// brw->pipe.set_feedback_buffer = brw_set_feedback_buffer;
brw->pipe.set_polygon_stipple = brw_set_polygon_stipple;
brw->pipe.set_scissor_state = brw_set_scissor_state;
brw->pipe.set_sampler_textures = brw_set_sampler_textures;
brw->pipe.set_viewport_state = brw_set_viewport_state;
brw->pipe.set_vertex_buffer = brw_set_vertex_buffer;
brw->pipe.set_vertex_element = brw_set_vertex_element;
}

View file

@ -235,7 +235,8 @@ static void upload_wm_samplers(struct brw_context *brw)
unsigned sampler_count = 0;
/* BRW_NEW_SAMPLER */
for (unit = 0; unit < BRW_MAX_TEX_UNIT; unit++) {
for (unit = 0; unit < brw->num_textures && unit < brw->num_samplers;
unit++) {
/* determine unit enable/disable by looking for a bound texture */
if (brw->attribs.Texture[unit]) {
const struct pipe_sampler_state *sampler = brw->attribs.Samplers[unit];

View file

@ -237,7 +237,7 @@ static void upload_wm_surfaces(struct brw_context *brw )
/* BRW_NEW_TEXTURE
*/
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {
for (i = 0; i < brw->num_textures && i < brw->num_samplers; i++) {
const struct brw_texture *texUnit = brw->attribs.Texture[i];
if (texUnit &&

View file

@ -1,243 +1,243 @@
/**************************************************************************
*
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "draw/draw_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "sp_clear.h"
#include "sp_context.h"
#include "sp_flush.h"
#include "sp_prim_setup.h"
#include "sp_prim_vbuf.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_texture.h"
#include "sp_winsys.h"
#include "sp_query.h"
/**
* Map any drawing surfaces which aren't already mapped
*/
void
softpipe_map_surfaces(struct softpipe_context *sp)
{
unsigned i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
}
sp_tile_cache_map_surfaces(sp->zsbuf_cache);
}
/**
* Unmap any mapped drawing surfaces
*/
void
softpipe_unmap_surfaces(struct softpipe_context *sp)
{
uint i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
sp_flush_tile_cache(sp, sp->zsbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
}
sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
}
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 );
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
softpipe->quad.shade->destroy( softpipe->quad.shade );
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
softpipe->quad.coverage->destroy( softpipe->quad.coverage );
softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
softpipe->quad.blend->destroy( softpipe->quad.blend );
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->zsbuf_cache);
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) {
pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
}
}
FREE( softpipe );
}
struct pipe_context *
softpipe_create( struct pipe_screen *screen,
struct pipe_winsys *pipe_winsys,
struct softpipe_winsys *softpipe_winsys )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
#if defined(__i386__) || defined(__386__)
softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
#else
softpipe->use_sse = FALSE;
#endif
softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
softpipe->pipe.winsys = pipe_winsys;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
/* state setters */
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
softpipe->pipe.bind_sampler_state = softpipe_bind_sampler_state;
softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
softpipe->pipe.create_fs_state = softpipe_create_fs_state;
softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
softpipe->pipe.create_vs_state = softpipe_create_vs_state;
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
softpipe->pipe.set_sampler_texture = softpipe_set_sampler_texture;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush;
softpipe_init_query_funcs( softpipe );
softpipe_init_texture_funcs( softpipe );
/*
* Alloc caches for accessing drawing surfaces and textures.
* Must be before quad stage setup!
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
softpipe->cbuf_cache[i] = sp_create_tile_cache();
softpipe->zsbuf_cache = sp_create_tile_cache();
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
softpipe->tex_cache[i] = sp_create_tile_cache();
/* setup quad rendering stages */
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
softpipe->quad.output = sp_quad_output_stage(softpipe);
softpipe->winsys = softpipe_winsys;
/*
* Create drawing context and plug our rendering stage into it.
*/
softpipe->draw = draw_create();
assert(softpipe->draw);
softpipe->setup = sp_draw_render_stage(softpipe);
if (GETENV( "SP_VBUF" ) != NULL) {
sp_init_vbuf(softpipe);
}
else {
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
}
/* plug in AA line/point stages */
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
#if USE_DRAW_STAGE_PSTIPPLE
/* Do polygon stipple w/ texture map + frag prog? */
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
#endif
sp_init_surface_functions(softpipe);
return &softpipe->pipe;
}
/**************************************************************************
*
* 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:
* Keith Whitwell <keith@tungstengraphics.com>
*/
#include "draw/draw_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "sp_clear.h"
#include "sp_context.h"
#include "sp_flush.h"
#include "sp_prim_setup.h"
#include "sp_prim_vbuf.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
#include "sp_texture.h"
#include "sp_winsys.h"
#include "sp_query.h"
/**
* Map any drawing surfaces which aren't already mapped
*/
void
softpipe_map_surfaces(struct softpipe_context *sp)
{
unsigned i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
sp_tile_cache_map_surfaces(sp->cbuf_cache[i]);
}
sp_tile_cache_map_surfaces(sp->zsbuf_cache);
}
/**
* Unmap any mapped drawing surfaces
*/
void
softpipe_unmap_surfaces(struct softpipe_context *sp)
{
uint i;
for (i = 0; i < sp->framebuffer.num_cbufs; i++)
sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
sp_flush_tile_cache(sp, sp->zsbuf_cache);
for (i = 0; i < sp->framebuffer.num_cbufs; i++) {
sp_tile_cache_unmap_surfaces(sp->cbuf_cache[i]);
}
sp_tile_cache_unmap_surfaces(sp->zsbuf_cache);
}
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 );
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
softpipe->quad.shade->destroy( softpipe->quad.shade );
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
softpipe->quad.stencil_test->destroy( softpipe->quad.stencil_test );
softpipe->quad.occlusion->destroy( softpipe->quad.occlusion );
softpipe->quad.coverage->destroy( softpipe->quad.coverage );
softpipe->quad.bufloop->destroy( softpipe->quad.bufloop );
softpipe->quad.blend->destroy( softpipe->quad.blend );
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->zsbuf_cache);
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) {
pipe_buffer_reference(ws, &softpipe->constants[i].buffer, NULL);
}
}
FREE( softpipe );
}
struct pipe_context *
softpipe_create( struct pipe_screen *screen,
struct pipe_winsys *pipe_winsys,
struct softpipe_winsys *softpipe_winsys )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
#if defined(__i386__) || defined(__386__)
softpipe->use_sse = GETENV( "GALLIUM_NOSSE" ) == NULL;
#else
softpipe->use_sse = FALSE;
#endif
softpipe->dump_fs = GETENV( "GALLIUM_DUMP_FS" ) != NULL;
softpipe->pipe.winsys = pipe_winsys;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
/* state setters */
softpipe->pipe.create_blend_state = softpipe_create_blend_state;
softpipe->pipe.bind_blend_state = softpipe_bind_blend_state;
softpipe->pipe.delete_blend_state = softpipe_delete_blend_state;
softpipe->pipe.create_sampler_state = softpipe_create_sampler_state;
softpipe->pipe.bind_sampler_states = softpipe_bind_sampler_states;
softpipe->pipe.delete_sampler_state = softpipe_delete_sampler_state;
softpipe->pipe.create_depth_stencil_alpha_state = softpipe_create_depth_stencil_state;
softpipe->pipe.bind_depth_stencil_alpha_state = softpipe_bind_depth_stencil_state;
softpipe->pipe.delete_depth_stencil_alpha_state = softpipe_delete_depth_stencil_state;
softpipe->pipe.create_rasterizer_state = softpipe_create_rasterizer_state;
softpipe->pipe.bind_rasterizer_state = softpipe_bind_rasterizer_state;
softpipe->pipe.delete_rasterizer_state = softpipe_delete_rasterizer_state;
softpipe->pipe.create_fs_state = softpipe_create_fs_state;
softpipe->pipe.bind_fs_state = softpipe_bind_fs_state;
softpipe->pipe.delete_fs_state = softpipe_delete_fs_state;
softpipe->pipe.create_vs_state = softpipe_create_vs_state;
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state;
softpipe->pipe.set_polygon_stipple = softpipe_set_polygon_stipple;
softpipe->pipe.set_scissor_state = softpipe_set_scissor_state;
softpipe->pipe.set_sampler_textures = softpipe_set_sampler_textures;
softpipe->pipe.set_viewport_state = softpipe_set_viewport_state;
softpipe->pipe.set_vertex_buffer = softpipe_set_vertex_buffer;
softpipe->pipe.set_vertex_element = softpipe_set_vertex_element;
softpipe->pipe.draw_arrays = softpipe_draw_arrays;
softpipe->pipe.draw_elements = softpipe_draw_elements;
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush;
softpipe_init_query_funcs( softpipe );
softpipe_init_texture_funcs( softpipe );
/*
* Alloc caches for accessing drawing surfaces and textures.
* Must be before quad stage setup!
*/
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
softpipe->cbuf_cache[i] = sp_create_tile_cache();
softpipe->zsbuf_cache = sp_create_tile_cache();
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
softpipe->tex_cache[i] = sp_create_tile_cache();
/* setup quad rendering stages */
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
softpipe->quad.stencil_test = sp_quad_stencil_test_stage(softpipe);
softpipe->quad.occlusion = sp_quad_occlusion_stage(softpipe);
softpipe->quad.coverage = sp_quad_coverage_stage(softpipe);
softpipe->quad.bufloop = sp_quad_bufloop_stage(softpipe);
softpipe->quad.blend = sp_quad_blend_stage(softpipe);
softpipe->quad.colormask = sp_quad_colormask_stage(softpipe);
softpipe->quad.output = sp_quad_output_stage(softpipe);
softpipe->winsys = softpipe_winsys;
/*
* Create drawing context and plug our rendering stage into it.
*/
softpipe->draw = draw_create();
assert(softpipe->draw);
softpipe->setup = sp_draw_render_stage(softpipe);
if (GETENV( "SP_VBUF" ) != NULL) {
sp_init_vbuf(softpipe);
}
else {
draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
}
/* plug in AA line/point stages */
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
#if USE_DRAW_STAGE_PSTIPPLE
/* Do polygon stipple w/ texture map + frag prog? */
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
#endif
sp_init_surface_functions(softpipe);
return &softpipe->pipe;
}

View file

@ -81,6 +81,9 @@ struct softpipe_context {
struct pipe_vertex_element vertex_element[PIPE_ATTRIB_MAX];
unsigned dirty;
unsigned num_samplers;
unsigned num_textures;
/* Counter for occlusion queries. Note this supports overlapping
* queries.
*/

View file

@ -1,208 +1,209 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
/* Vertices are just an array of floats, with all the attributes
* packed. We currently assume a layout like:
*
* attr[0][0..3] - window position
* attr[1..n][0..3] - remaining attributes.
*
* Attributes are assumed to be 4 floats wide but are packed so that
* all the enabled attributes run contiguously.
*/
#include "pipe/p_util.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_headers.h"
#include "sp_quad.h"
#include "sp_texture.h"
#include "sp_tex_sample.h"
struct quad_shade_stage
{
struct quad_stage stage;
struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
struct tgsi_exec_machine machine;
struct tgsi_exec_vector *inputs, *outputs;
int colorOutSlot, depthOutSlot;
};
/** cast wrapper */
static INLINE struct quad_shade_stage *
quad_shade_stage(struct quad_stage *qs)
{
return (struct quad_shade_stage *) qs;
}
/**
* Execute fragment shader for the four fragments in the quad.
*/
static void
shade_quad(
struct quad_stage *qs,
struct quad_header *quad )
{
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
struct tgsi_exec_machine *machine = &qss->machine;
/* Consts do not require 16 byte alignment. */
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
machine->InterpCoefs = quad->coef;
/* run shader */
quad->mask &= softpipe->fs->run( softpipe->fs,
&qss->machine,
quad );
/* store result color */
if (qss->colorOutSlot >= 0) {
/* XXX need to handle multiple color outputs someday */
assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
memcpy(
quad->outputs.color,
&machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
sizeof( quad->outputs.color ) );
}
/*
* XXX the following code for updating quad->outputs.depth
* isn't really needed if we did early z testing.
*/
/* store result Z */
if (qss->depthOutSlot >= 0) {
/* output[slot] is new Z */
uint i;
for (i = 0; i < 4; i++) {
quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
}
}
else {
/* copy input Z (which was interpolated by the executor) to output Z */
uint i;
for (i = 0; i < 4; i++) {
quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
/* XXX not sure the above line is always correct. The following
* might be better:
quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
*/
}
}
/* shader may cull fragments */
if( quad->mask ) {
qs->next->run( qs->next, quad );
}
}
/**
* Per-primitive (or per-begin?) setup
*/
static void shade_begin(struct quad_stage *qs)
{
struct quad_shade_stage *qss = quad_shade_stage(qs);
struct softpipe_context *softpipe = qs->softpipe;
unsigned i;
/* set TGSI sampler state that varies */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
qss->samplers[i].state = softpipe->sampler[i];
qss->samplers[i].texture = softpipe->texture[i];
}
/* find output slots for depth, color */
qss->colorOutSlot = -1;
qss->depthOutSlot = -1;
for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
qss->depthOutSlot = i;
break;
case TGSI_SEMANTIC_COLOR:
qss->colorOutSlot = i;
break;
}
}
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
qss->samplers );
qs->next->begin(qs->next);
}
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 );
}
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
{
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
uint i;
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
qss->machine.Inputs = align16(qss->inputs);
qss->machine.Outputs = align16(qss->outputs);
qss->stage.softpipe = softpipe;
qss->stage.begin = shade_begin;
qss->stage.run = shade_quad;
qss->stage.destroy = shade_destroy;
/* set TGSI sampler state that's constant */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
assert(softpipe->tex_cache[i]);
qss->samplers[i].get_samples = sp_get_samples;
qss->samplers[i].pipe = &softpipe->pipe;
qss->samplers[i].cache = softpipe->tex_cache[i];
}
tgsi_exec_machine_init( &qss->machine );
return &qss->stage;
}
/**************************************************************************
*
* 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.
*
**************************************************************************/
/* Vertices are just an array of floats, with all the attributes
* packed. We currently assume a layout like:
*
* attr[0][0..3] - window position
* attr[1..n][0..3] - remaining attributes.
*
* Attributes are assumed to be 4 floats wide but are packed so that
* all the enabled attributes run contiguously.
*/
#include "pipe/p_util.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_headers.h"
#include "sp_quad.h"
#include "sp_texture.h"
#include "sp_tex_sample.h"
struct quad_shade_stage
{
struct quad_stage stage;
struct tgsi_sampler samplers[PIPE_MAX_SAMPLERS];
struct tgsi_exec_machine machine;
struct tgsi_exec_vector *inputs, *outputs;
int colorOutSlot, depthOutSlot;
};
/** cast wrapper */
static INLINE struct quad_shade_stage *
quad_shade_stage(struct quad_stage *qs)
{
return (struct quad_shade_stage *) qs;
}
/**
* Execute fragment shader for the four fragments in the quad.
*/
static void
shade_quad(
struct quad_stage *qs,
struct quad_header *quad )
{
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
struct tgsi_exec_machine *machine = &qss->machine;
/* Consts do not require 16 byte alignment. */
machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
machine->InterpCoefs = quad->coef;
/* run shader */
quad->mask &= softpipe->fs->run( softpipe->fs,
&qss->machine,
quad );
/* store result color */
if (qss->colorOutSlot >= 0) {
/* XXX need to handle multiple color outputs someday */
assert(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
== TGSI_SEMANTIC_COLOR);
memcpy(
quad->outputs.color,
&machine->Outputs[qss->colorOutSlot].xyzw[0].f[0],
sizeof( quad->outputs.color ) );
}
/*
* XXX the following code for updating quad->outputs.depth
* isn't really needed if we did early z testing.
*/
/* store result Z */
if (qss->depthOutSlot >= 0) {
/* output[slot] is new Z */
uint i;
for (i = 0; i < 4; i++) {
quad->outputs.depth[i] = machine->Outputs[0].xyzw[2].f[i];
}
}
else {
/* copy input Z (which was interpolated by the executor) to output Z */
uint i;
for (i = 0; i < 4; i++) {
quad->outputs.depth[i] = machine->Inputs[0].xyzw[2].f[i];
/* XXX not sure the above line is always correct. The following
* might be better:
quad->outputs.depth[i] = machine->QuadPos.xyzw[2].f[i];
*/
}
}
/* shader may cull fragments */
if( quad->mask ) {
qs->next->run( qs->next, quad );
}
}
/**
* Per-primitive (or per-begin?) setup
*/
static void shade_begin(struct quad_stage *qs)
{
struct quad_shade_stage *qss = quad_shade_stage(qs);
struct softpipe_context *softpipe = qs->softpipe;
unsigned i;
unsigned num = MAX2(softpipe->num_textures, softpipe->num_samplers);
/* set TGSI sampler state that varies */
for (i = 0; i < num; i++) {
qss->samplers[i].state = softpipe->sampler[i];
qss->samplers[i].texture = softpipe->texture[i];
}
/* find output slots for depth, color */
qss->colorOutSlot = -1;
qss->depthOutSlot = -1;
for (i = 0; i < qss->stage.softpipe->fs->info.num_outputs; i++) {
switch (qss->stage.softpipe->fs->info.output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
qss->depthOutSlot = i;
break;
case TGSI_SEMANTIC_COLOR:
qss->colorOutSlot = i;
break;
}
}
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
qss->samplers );
qs->next->begin(qs->next);
}
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 );
}
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
{
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
uint i;
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
qss->inputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->inputs) + 16);
qss->outputs = MALLOC(PIPE_ATTRIB_MAX * sizeof(*qss->outputs) + 16);
qss->machine.Inputs = align16(qss->inputs);
qss->machine.Outputs = align16(qss->outputs);
qss->stage.softpipe = softpipe;
qss->stage.begin = shade_begin;
qss->stage.run = shade_quad;
qss->stage.destroy = shade_destroy;
/* set TGSI sampler state that's constant */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
assert(softpipe->tex_cache[i]);
qss->samplers[i].get_samples = sp_get_samples;
qss->samplers[i].pipe = &softpipe->pipe;
qss->samplers[i].cache = softpipe->tex_cache[i];
}
tgsi_exec_machine_init( &qss->machine );
return &qss->stage;
}

View file

@ -1,195 +1,195 @@
/**************************************************************************
*
* 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 SP_STATE_H
#define SP_STATE_H
#include "pipe/p_state.h"
#include "tgsi/util/tgsi_scan.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
struct tgsi_sampler;
struct tgsi_exec_machine;
/** Subclass of pipe_shader_state (though it doesn't really need to be).
*
* This is starting to look an awful lot like a quad pipeline stage...
*/
struct sp_fragment_shader {
struct pipe_shader_state shader;
struct tgsi_shader_info info;
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler *samplers);
/* Run the shader - this interface will get cleaned up in the
* future:
*/
unsigned (*run)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct quad_header *quad );
void (*delete)( struct sp_fragment_shader * );
};
struct vertex_info;
/** Subclass of pipe_shader_state */
struct sp_vertex_shader {
struct pipe_shader_state shader;
struct draw_vertex_shader *draw_data;
};
void *
softpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);
void softpipe_bind_blend_state(struct pipe_context *,
void *);
void softpipe_delete_blend_state(struct pipe_context *,
void *);
void *
softpipe_create_sampler_state(struct pipe_context *,
const struct pipe_sampler_state *);
void softpipe_bind_sampler_state(struct pipe_context *, unsigned, void *);
void softpipe_delete_sampler_state(struct pipe_context *, void *);
void *
softpipe_create_depth_stencil_state(struct pipe_context *,
const struct pipe_depth_stencil_alpha_state *);
void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
void *
softpipe_create_rasterizer_state(struct pipe_context *,
const struct pipe_rasterizer_state *);
void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
void softpipe_set_framebuffer_state( struct pipe_context *,
const struct pipe_framebuffer_state * );
void softpipe_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color );
void softpipe_set_clip_state( struct pipe_context *,
const struct pipe_clip_state * );
void softpipe_set_constant_buffer(struct pipe_context *,
uint shader, uint index,
const struct pipe_constant_buffer *buf);
void *softpipe_create_fs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_fs_state(struct pipe_context *, void *);
void softpipe_delete_fs_state(struct pipe_context *, void *);
void *softpipe_create_vs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_vs_state(struct pipe_context *, void *);
void softpipe_delete_vs_state(struct pipe_context *, void *);
void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
void softpipe_set_sampler_texture( struct pipe_context *,
unsigned unit,
struct pipe_texture * );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void softpipe_set_vertex_element(struct pipe_context *,
unsigned index,
const struct pipe_vertex_element *);
void softpipe_set_vertex_buffer(struct pipe_context *,
unsigned index,
const struct pipe_vertex_buffer *);
void softpipe_update_derived( struct softpipe_context *softpipe );
boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
boolean softpipe_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
void
softpipe_map_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_surfaces(struct softpipe_context *sp);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
struct vertex_info *
softpipe_get_vertex_info(struct softpipe_context *softpipe);
struct vertex_info *
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
#endif
/**************************************************************************
*
* 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 SP_STATE_H
#define SP_STATE_H
#include "pipe/p_state.h"
#include "tgsi/util/tgsi_scan.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
struct tgsi_sampler;
struct tgsi_exec_machine;
/** Subclass of pipe_shader_state (though it doesn't really need to be).
*
* This is starting to look an awful lot like a quad pipeline stage...
*/
struct sp_fragment_shader {
struct pipe_shader_state shader;
struct tgsi_shader_info info;
void (*prepare)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct tgsi_sampler *samplers);
/* Run the shader - this interface will get cleaned up in the
* future:
*/
unsigned (*run)( const struct sp_fragment_shader *shader,
struct tgsi_exec_machine *machine,
struct quad_header *quad );
void (*delete)( struct sp_fragment_shader * );
};
struct vertex_info;
/** Subclass of pipe_shader_state */
struct sp_vertex_shader {
struct pipe_shader_state shader;
struct draw_vertex_shader *draw_data;
};
void *
softpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);
void softpipe_bind_blend_state(struct pipe_context *,
void *);
void softpipe_delete_blend_state(struct pipe_context *,
void *);
void *
softpipe_create_sampler_state(struct pipe_context *,
const struct pipe_sampler_state *);
void softpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
void softpipe_delete_sampler_state(struct pipe_context *, void *);
void *
softpipe_create_depth_stencil_state(struct pipe_context *,
const struct pipe_depth_stencil_alpha_state *);
void softpipe_bind_depth_stencil_state(struct pipe_context *, void *);
void softpipe_delete_depth_stencil_state(struct pipe_context *, void *);
void *
softpipe_create_rasterizer_state(struct pipe_context *,
const struct pipe_rasterizer_state *);
void softpipe_bind_rasterizer_state(struct pipe_context *, void *);
void softpipe_delete_rasterizer_state(struct pipe_context *, void *);
void softpipe_set_framebuffer_state( struct pipe_context *,
const struct pipe_framebuffer_state * );
void softpipe_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color );
void softpipe_set_clip_state( struct pipe_context *,
const struct pipe_clip_state * );
void softpipe_set_constant_buffer(struct pipe_context *,
uint shader, uint index,
const struct pipe_constant_buffer *buf);
void *softpipe_create_fs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_fs_state(struct pipe_context *, void *);
void softpipe_delete_fs_state(struct pipe_context *, void *);
void *softpipe_create_vs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_vs_state(struct pipe_context *, void *);
void softpipe_delete_vs_state(struct pipe_context *, void *);
void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );
void softpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
void softpipe_set_sampler_textures( struct pipe_context *,
unsigned num,
struct pipe_texture ** );
void softpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void softpipe_set_vertex_element(struct pipe_context *,
unsigned index,
const struct pipe_vertex_element *);
void softpipe_set_vertex_buffer(struct pipe_context *,
unsigned index,
const struct pipe_vertex_buffer *);
void softpipe_update_derived( struct softpipe_context *softpipe );
boolean softpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
boolean softpipe_draw_elements(struct pipe_context *pipe,
struct pipe_buffer *indexBuffer,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count);
void
softpipe_map_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_surfaces(struct softpipe_context *sp);
void
softpipe_map_texture_surfaces(struct softpipe_context *sp);
void
softpipe_unmap_texture_surfaces(struct softpipe_context *sp);
struct vertex_info *
softpipe_get_vertex_info(struct softpipe_context *softpipe);
struct vertex_info *
softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe);
#endif

View file

@ -50,21 +50,61 @@ softpipe_create_sampler_state(struct pipe_context *pipe,
return mem_dup(sampler, sizeof(*sampler));
}
void
softpipe_bind_sampler_state(struct pipe_context *pipe,
unsigned unit, void *sampler)
softpipe_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == softpipe->num_samplers &&
!memcmp(softpipe->sampler, sampler, num * sizeof(void *)))
return;
draw_flush(softpipe->draw);
assert(unit < PIPE_MAX_SAMPLERS);
softpipe->sampler[unit] = (struct pipe_sampler_state *)sampler;
memcpy(softpipe->sampler, sampler, num * sizeof(void *));
memset(&softpipe->sampler[num], 0, (PIPE_MAX_SAMPLERS - num) *
sizeof(void *));
softpipe->num_samplers = num;
softpipe->dirty |= SP_NEW_SAMPLER;
}
void
softpipe_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint i;
assert(num <= PIPE_MAX_SAMPLERS);
/* Check for no-op */
if (num == softpipe->num_textures &&
!memcmp(softpipe->texture, texture, num * sizeof(struct pipe_texture *)))
return;
draw_flush(softpipe->draw);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
struct pipe_texture *tex = i < num ? texture[i] : NULL;
pipe_texture_reference(&softpipe->texture[i], tex);
sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex);
}
softpipe->num_textures = num;
softpipe->dirty |= SP_NEW_TEXTURE;
}
void
softpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
@ -73,22 +113,4 @@ softpipe_delete_sampler_state(struct pipe_context *pipe,
}
void
softpipe_set_sampler_texture(struct pipe_context *pipe,
unsigned unit,
struct pipe_texture *texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
draw_flush(softpipe->draw);
assert(unit < PIPE_MAX_SAMPLERS);
pipe_texture_reference(&softpipe->texture[unit], texture);
sp_tile_cache_set_texture(pipe, softpipe->tex_cache[unit], texture);
softpipe->dirty |= SP_NEW_TEXTURE;
}

View file

@ -1,202 +1,202 @@
/**************************************************************************
*
* Copyright 2006 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>
* Michel Dänzer <michel@tungstengraphics.com>
*/
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
#include "sp_tile_cache.h"
/* Simple, maximally packed layout.
*/
static unsigned minify( unsigned d )
{
return MAX2(1, d>>1);
}
static void
softpipe_texture_layout(struct softpipe_texture * spt)
{
struct pipe_texture *pt = &spt->base;
unsigned level;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
spt->buffer_size = 0;
for (level = 0; level <= pt->last_level; level++) {
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
spt->level_offset[level] = spt->buffer_size;
spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
width * pt->cpp;
width = minify(width);
height = minify(height);
depth = minify(depth);
}
}
static struct pipe_texture *
softpipe_texture_create_screen(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
spt->base = *templat;
spt->base.refcount = 1;
spt->base.screen = screen;
softpipe_texture_layout(spt);
spt->buffer = ws->buffer_create(ws, 32,
PIPE_BUFFER_USAGE_PIXEL,
spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
return NULL;
}
assert(spt->base.refcount == 1);
return &spt->base;
}
static void
softpipe_texture_release_screen(struct pipe_screen *screen,
struct pipe_texture **pt)
{
if (!*pt)
return;
/*
DBG("%s %p refcount will be %d\n",
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
*/
if (--(*pt)->refcount <= 0) {
struct softpipe_texture *spt = softpipe_texture(*pt);
/*
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
FREE(spt);
}
*pt = NULL;
}
static struct pipe_surface *
softpipe_get_tex_surface_screen(struct pipe_screen *screen,
struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
ps = ws->surface_alloc(ws);
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
ps->pitch = ps->width;
ps->offset = spt->level_offset[level];
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
(pt->compressed ? ps->height/4 : ps->height) *
ps->width * ps->cpp;
}
else {
assert(face == 0);
assert(zslice == 0);
}
}
return ps;
}
static void
softpipe_texture_update(struct pipe_context *pipe,
struct pipe_texture *texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint unit;
for (unit = 0; unit < PIPE_MAX_SAMPLERS; unit++) {
if (softpipe->texture[unit] == texture) {
sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
}
}
}
void
softpipe_init_texture_funcs( struct softpipe_context *softpipe )
{
softpipe->pipe.texture_update = softpipe_texture_update;
}
void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create_screen;
screen->texture_release = softpipe_texture_release_screen;
screen->get_tex_surface = softpipe_get_tex_surface_screen;
}
/**************************************************************************
*
* Copyright 2006 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>
* Michel Dänzer <michel@tungstengraphics.com>
*/
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "pipe/p_util.h"
#include "pipe/p_winsys.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
#include "sp_tile_cache.h"
/* Simple, maximally packed layout.
*/
static unsigned minify( unsigned d )
{
return MAX2(1, d>>1);
}
static void
softpipe_texture_layout(struct softpipe_texture * spt)
{
struct pipe_texture *pt = &spt->base;
unsigned level;
unsigned width = pt->width[0];
unsigned height = pt->height[0];
unsigned depth = pt->depth[0];
spt->buffer_size = 0;
for (level = 0; level <= pt->last_level; level++) {
pt->width[level] = width;
pt->height[level] = height;
pt->depth[level] = depth;
spt->level_offset[level] = spt->buffer_size;
spt->buffer_size += ((pt->compressed) ? MAX2(1, height/4) : height) *
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
width * pt->cpp;
width = minify(width);
height = minify(height);
depth = minify(depth);
}
}
static struct pipe_texture *
softpipe_texture_create_screen(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
spt->base = *templat;
spt->base.refcount = 1;
spt->base.screen = screen;
softpipe_texture_layout(spt);
spt->buffer = ws->buffer_create(ws, 32,
PIPE_BUFFER_USAGE_PIXEL,
spt->buffer_size);
if (!spt->buffer) {
FREE(spt);
return NULL;
}
assert(spt->base.refcount == 1);
return &spt->base;
}
static void
softpipe_texture_release_screen(struct pipe_screen *screen,
struct pipe_texture **pt)
{
if (!*pt)
return;
/*
DBG("%s %p refcount will be %d\n",
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
*/
if (--(*pt)->refcount <= 0) {
struct softpipe_texture *spt = softpipe_texture(*pt);
/*
DBG("%s deleting %p\n", __FUNCTION__, (void *) spt);
*/
pipe_buffer_reference(screen->winsys, &spt->buffer, NULL);
FREE(spt);
}
*pt = NULL;
}
static struct pipe_surface *
softpipe_get_tex_surface_screen(struct pipe_screen *screen,
struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice)
{
struct pipe_winsys *ws = screen->winsys;
struct softpipe_texture *spt = softpipe_texture(pt);
struct pipe_surface *ps;
assert(level <= pt->last_level);
ps = ws->surface_alloc(ws);
if (ps) {
assert(ps->refcount);
assert(ps->winsys);
pipe_buffer_reference(ws, &ps->buffer, spt->buffer);
ps->format = pt->format;
ps->cpp = pt->cpp;
ps->width = pt->width[level];
ps->height = pt->height[level];
ps->pitch = ps->width;
ps->offset = spt->level_offset[level];
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) {
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) *
(pt->compressed ? ps->height/4 : ps->height) *
ps->width * ps->cpp;
}
else {
assert(face == 0);
assert(zslice == 0);
}
}
return ps;
}
static void
softpipe_texture_update(struct pipe_context *pipe,
struct pipe_texture *texture)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
uint unit;
for (unit = 0; unit < softpipe->num_textures; unit++) {
if (softpipe->texture[unit] == texture) {
sp_flush_tile_cache(softpipe, softpipe->tex_cache[unit]);
}
}
}
void
softpipe_init_texture_funcs( struct softpipe_context *softpipe )
{
softpipe->pipe.texture_update = softpipe_texture_update;
}
void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create_screen;
screen->texture_release = softpipe_texture_release_screen;
screen->get_tex_surface = softpipe_get_tex_surface_screen;
}

View file

@ -100,7 +100,7 @@ struct pipe_context {
void * (*create_sampler_state)(struct pipe_context *,
const struct pipe_sampler_state *);
void (*bind_sampler_state)(struct pipe_context *, unsigned unit, void *);
void (*bind_sampler_states)(struct pipe_context *, unsigned num, void **);
void (*delete_sampler_state)(struct pipe_context *, void *);
void * (*create_rasterizer_state)(struct pipe_context *,
@ -148,9 +148,9 @@ struct pipe_context {
/* Currently a sampler is constrained to sample from a single texture:
*/
void (*set_sampler_texture)( struct pipe_context *,
unsigned sampler,
struct pipe_texture * );
void (*set_sampler_textures)( struct pipe_context *,
unsigned num,
struct pipe_texture ** );
void (*set_viewport_state)( struct pipe_context *,
const struct pipe_viewport_state * );

View file

@ -120,10 +120,11 @@ update_samplers(struct st_context *st)
const struct st_fragment_program *fs = st->fp;
GLuint su;
st->state.num_samplers = 0;
/* loop over sampler units (aka tex image units) */
for (su = 0; su < st->ctx->Const.MaxTextureImageUnits; su++) {
struct pipe_sampler_state sampler;
const struct cso_sampler *cso;
memset(&sampler, 0, sizeof(sampler));
@ -168,17 +169,16 @@ update_samplers(struct st_context *st)
= st_compare_func_to_pipe(texobj->CompareFunc);
}
st->state.num_samplers = su + 1;
/* XXX more sampler state here */
}
cso = st_cached_sampler_state(st, &sampler);
if (cso != st->state.sampler[su]) {
/* state has changed */
st->state.sampler[su] = cso;
st->pipe->bind_sampler_state(st->pipe, su, cso->data);
}
st->state.sampler[su] = st_cached_sampler_state(st, &sampler)->data;
}
st->pipe->bind_sampler_states(st->pipe, st->state.num_samplers,
st->state.sampler);
}

View file

@ -37,6 +37,7 @@
#include "st_texture.h"
#include "st_cb_texture.h"
#include "pipe/p_context.h"
#include "pipe/p_inlines.h"
/**
@ -51,6 +52,8 @@ update_textures(struct st_context *st)
struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current;
GLuint unit;
st->state.num_textures = 0;
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;
@ -62,6 +65,8 @@ update_textures(struct st_context *st)
retval = st_finalize_texture(st->ctx, st->pipe, texObj, &flush);
/* XXX retval indicates whether there's a texture border */
st->state.num_textures = unit + 1;
}
/* XXX: need to ensure that textures are unbound/removed from
@ -70,18 +75,16 @@ update_textures(struct st_context *st)
*/
pt = st_get_stobj_texture(stObj);
if (st->state.sampler_texture[unit] != pt) {
st->state.sampler_texture[unit] = pt;
st->pipe->set_sampler_texture(st->pipe, unit, pt);
}
pipe_texture_reference(&st->state.sampler_texture[unit], pt);
if (stObj && stObj->dirtyData) {
st->pipe->texture_update(st->pipe, pt);
stObj->dirtyData = GL_FALSE;
}
}
st->pipe->set_sampler_textures(st->pipe, st->state.num_textures,
st->state.sampler_texture);
}

View file

@ -641,7 +641,6 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
const GLfloat *color,
GLboolean invertTex)
{
const GLuint unit = 0;
struct pipe_context *pipe = ctx->st->pipe;
GLfloat x0, y0, x1, y1;
GLuint maxSize;
@ -684,7 +683,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
sampler.normalized_coords = 1;
cso = st_cached_sampler_state(ctx->st, &sampler);
pipe->bind_sampler_state(pipe, unit, cso->data);
pipe->bind_sampler_states(pipe, 1, (void**)&cso->data);
}
/* viewport state: viewport matching window dims */
@ -705,7 +704,7 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
/* texture state: */
{
pipe->set_sampler_texture(pipe, unit, pt);
pipe->set_sampler_textures(pipe, 1, &pt);
}
/* Compute window coords (y=0=bottom) with pixel zoom.
@ -727,8 +726,10 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
pipe->bind_rasterizer_state(pipe, ctx->st->state.rasterizer->data);
pipe->bind_fs_state(pipe, ctx->st->state.fs->data);
pipe->bind_vs_state(pipe, ctx->st->state.vs->cso->data);
pipe->set_sampler_texture(pipe, unit, ctx->st->state.sampler_texture[unit]);
pipe->bind_sampler_state(pipe, unit, ctx->st->state.sampler[unit]->data);
pipe->set_sampler_textures(pipe, ctx->st->state.num_textures,
ctx->st->state.sampler_texture);
pipe->bind_sampler_states(pipe, ctx->st->state.num_samplers,
ctx->st->state.sampler);
pipe->set_viewport_state(pipe, &ctx->st->state.viewport);
}

View file

@ -76,7 +76,7 @@ struct st_context
struct {
const struct cso_alpha_test *alpha_test;
const struct cso_blend *blend;
const struct cso_sampler *sampler[PIPE_MAX_SAMPLERS];
void *sampler[PIPE_MAX_SAMPLERS];
const struct cso_depth_stencil_alpha *depth_stencil;
const struct cso_rasterizer *rasterizer;
const struct cso_fragment_shader *fs;
@ -90,6 +90,9 @@ struct st_context
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_viewport_state viewport;
GLuint num_samplers;
GLuint num_textures;
} state;
struct {

View file

@ -284,7 +284,7 @@ st_render_mipmap(struct st_context *st,
*/
sampler.min_lod = sampler.max_lod = srcLevel;
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
pipe->bind_sampler_state(pipe, 0, sampler_cso);
pipe->bind_sampler_states(pipe, 1, &sampler_cso);
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
@ -293,7 +293,7 @@ st_render_mipmap(struct st_context *st,
* the right mipmap level.
*/
/*pt->first_level = srcLevel;*/
pipe->set_sampler_texture(pipe, 0, pt);
pipe->set_sampler_textures(pipe, 1, &pt);
draw_quad(st->ctx);
@ -310,9 +310,10 @@ st_render_mipmap(struct st_context *st,
pipe->bind_fs_state(pipe, st->state.fs->data);
if (st->state.vs)
pipe->bind_vs_state(pipe, st->state.vs->cso->data);
if (st->state.sampler[0])
pipe->bind_sampler_state(pipe, 0, st->state.sampler[0]->data);
pipe->set_sampler_texture(pipe, 0, st->state.sampler_texture[0]);
pipe->bind_sampler_states(pipe, st->state.num_samplers,
st->state.sampler);
pipe->set_sampler_textures(pipe, st->state.num_textures,
st->state.sampler_texture);
pipe->set_viewport_state(pipe, &st->state.viewport);
return TRUE;