mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 15:38:09 +02:00
First stab at immutable state objects (create/bind/delete)
We want our state objects to be immutable, handled via the create/bind/delete calls instead of struct propagation. Only implementing the blend state to see how it would look like and work.
This commit is contained in:
parent
ffacb1c12a
commit
9780327c5d
23 changed files with 382 additions and 59 deletions
176
src/mesa/cso_cache/cso_cache.c
Normal file
176
src/mesa/cso_cache/cso_cache.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#include "cso_cache.h"
|
||||
|
||||
#if 1
|
||||
static unsigned hash_key( const void *key, unsigned key_size )
|
||||
{
|
||||
unsigned *ikey = (unsigned *)key;
|
||||
unsigned hash = 0, i;
|
||||
|
||||
assert(key_size % 4 == 0);
|
||||
|
||||
/* I'm sure this can be improved on:
|
||||
*/
|
||||
for (i = 0; i < key_size/4; i++)
|
||||
hash ^= ikey[i];
|
||||
|
||||
return hash;
|
||||
}
|
||||
#else
|
||||
static unsigned hash_key(const unsigned char *p, int n)
|
||||
{
|
||||
unsigned h = 0;
|
||||
unsigned g;
|
||||
|
||||
while (n--) {
|
||||
h = (h << 4) + *p++;
|
||||
if ((g = (h & 0xf0000000)) != 0)
|
||||
h ^= g >> 23;
|
||||
h &= ~g;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned cso_construct_key(void *item, int item_size)
|
||||
{
|
||||
return hash_key((const unsigned char*)(item), item_size);
|
||||
}
|
||||
|
||||
struct cso_cache_item *
|
||||
cso_insert_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size)
|
||||
{
|
||||
struct cso_cache_item *found_state =
|
||||
_mesa_HashLookup(sc->hash, hash_key);
|
||||
struct cso_cache_item *item =
|
||||
malloc(sizeof(struct cso_cache_item));
|
||||
_mesa_printf("inserting state ========= key = %d\n", hash_key);
|
||||
item->key = hash_key;
|
||||
item->state_size = state_size;
|
||||
item->state = state;
|
||||
item->next = 0;
|
||||
|
||||
if (found_state) {
|
||||
while (found_state->next)
|
||||
found_state = found_state->next;
|
||||
found_state->next = item;
|
||||
} else
|
||||
_mesa_HashInsert(sc->hash, hash_key, item);
|
||||
return item;
|
||||
}
|
||||
|
||||
struct cso_cache_item *
|
||||
cso_find_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size)
|
||||
{
|
||||
struct cso_cache_item *found_state =
|
||||
_mesa_HashLookup(sc->hash, hash_key);
|
||||
|
||||
while (found_state &&
|
||||
(found_state->state_size != state_size ||
|
||||
memcmp(found_state->state, state, state_size))) {
|
||||
found_state = found_state->next;
|
||||
}
|
||||
|
||||
_mesa_printf("finding state ========== %d (%p)\n", hash_key, found_state);
|
||||
return found_state;
|
||||
}
|
||||
|
||||
struct cso_cache_item *
|
||||
cso_remove_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size)
|
||||
{
|
||||
struct cso_cache_item *found_state =
|
||||
_mesa_HashLookup(sc->hash, hash_key);
|
||||
struct cso_cache_item *prev = 0;
|
||||
|
||||
while (found_state &&
|
||||
(found_state->state_size != state_size ||
|
||||
memcmp(found_state->state, state, state_size))) {
|
||||
prev = found_state;
|
||||
found_state = found_state->next;
|
||||
}
|
||||
if (found_state) {
|
||||
if (prev)
|
||||
prev->next = found_state->next;
|
||||
else {
|
||||
if (found_state->next)
|
||||
_mesa_HashInsert(sc->hash, hash_key, found_state->next);
|
||||
else
|
||||
_mesa_HashRemove(sc->hash, hash_key);
|
||||
}
|
||||
}
|
||||
return found_state;
|
||||
}
|
||||
|
||||
struct cso_cache *cso_cache_create(void)
|
||||
{
|
||||
struct cso_cache *sc = malloc(sizeof(struct cso_cache));
|
||||
|
||||
sc->hash = _mesa_NewHashTable();
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
void cso_cache_destroy(struct cso_cache *sc)
|
||||
{
|
||||
assert(sc);
|
||||
assert(sc->hash);
|
||||
_mesa_DeleteHashTable(sc->hash);
|
||||
free(sc);
|
||||
}
|
||||
|
||||
/* This function will either find the state of the given template
|
||||
* in the cache or it will create a new state state from the given
|
||||
* template, will insert it in the cache and return it.
|
||||
*/
|
||||
struct pipe_blend_state * cso_cached_blend_state(
|
||||
struct st_context *st,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
unsigned hash_key = cso_construct_key((void*)blend, sizeof(struct pipe_blend_state));
|
||||
struct cso_cache_item *cache_item = cso_find_state(st->cache,
|
||||
hash_key,
|
||||
(void*)blend,
|
||||
sizeof(struct pipe_blend_state));
|
||||
if (!cache_item) {
|
||||
const struct pipe_blend_state *created_state = st->pipe->create_blend_state(
|
||||
st->pipe, blend);
|
||||
cache_item = cso_insert_state(st->cache, hash_key,
|
||||
(void*)created_state, sizeof(struct pipe_blend_state));
|
||||
}
|
||||
return (struct pipe_blend_state*)cache_item->state;
|
||||
}
|
||||
75
src/mesa/cso_cache/cso_cache.h
Normal file
75
src/mesa/cso_cache/cso_cache.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
|
||||
#ifndef CSO_CACHE_H
|
||||
#define CSO_CACHE_H
|
||||
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
#include "main/hash.h"
|
||||
|
||||
struct cso_cache_item {
|
||||
unsigned key;
|
||||
|
||||
unsigned state_size;
|
||||
const void *state;
|
||||
|
||||
struct cso_cache_item *next;
|
||||
};
|
||||
|
||||
struct cso_cache {
|
||||
struct _mesa_HashTable *hash;
|
||||
};
|
||||
|
||||
void cso_cache_destroy(struct cso_cache *sc);
|
||||
struct cso_cache *cso_cache_create(void);
|
||||
|
||||
unsigned cso_construct_key(void *item, int item_size);
|
||||
|
||||
struct cso_cache_item *cso_insert_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size);
|
||||
struct cso_cache_item *cso_find_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size);
|
||||
struct cso_cache_item *cso_remove_state(struct cso_cache *sc,
|
||||
unsigned hash_key,
|
||||
void *state, int state_size);
|
||||
|
||||
struct pipe_blend_state *cso_cached_blend_state(
|
||||
struct st_context *pipe,
|
||||
const struct pipe_blend_state *state);
|
||||
|
||||
#endif
|
||||
|
|
@ -67,8 +67,9 @@ struct failover_context {
|
|||
|
||||
/* The most recent drawing state as set by the driver:
|
||||
*/
|
||||
const struct pipe_blend_state *blend;
|
||||
|
||||
struct pipe_alpha_test_state alpha_test;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clear_color_state clear_color;
|
||||
struct pipe_clip_state clip;
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ failover_set_alpha_test_state(struct pipe_context *pipe,
|
|||
|
||||
|
||||
static void
|
||||
failover_set_blend_state( struct pipe_context *pipe,
|
||||
failover_bind_blend_state( struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend )
|
||||
{
|
||||
struct failover_context *failover = failover_context(pipe);
|
||||
|
||||
failover->blend = *blend;
|
||||
failover->blend = blend;
|
||||
failover->dirty |= FO_NEW_BLEND;
|
||||
failover->hw->set_blend_state( failover->hw, blend );
|
||||
failover->hw->bind_blend_state( failover->hw, blend );
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -266,9 +266,10 @@ failover_set_vertex_element(struct pipe_context *pipe,
|
|||
void
|
||||
failover_init_state_functions( struct failover_context *failover )
|
||||
{
|
||||
failover->pipe.bind_blend_state = failover_bind_blend_state;
|
||||
|
||||
failover->pipe.set_alpha_test_state = failover_set_alpha_test_state;
|
||||
failover->pipe.set_blend_color = failover_set_blend_color;
|
||||
failover->pipe.set_blend_state = failover_set_blend_state;
|
||||
failover->pipe.set_clip_state = failover_set_clip_state;
|
||||
failover->pipe.set_clear_color_state = failover_set_clear_color_state;
|
||||
failover->pipe.set_depth_state = failover_set_depth_test_state;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ failover_state_emit( struct failover_context *failover )
|
|||
failover->sw->set_alpha_test_state( failover->sw, &failover->alpha_test );
|
||||
|
||||
if (failover->dirty & FO_NEW_BLEND)
|
||||
failover->sw->set_blend_state( failover->sw, &failover->blend );
|
||||
failover->sw->bind_blend_state( failover->sw, failover->blend );
|
||||
|
||||
if (failover->dirty & FO_NEW_BLEND_COLOR)
|
||||
failover->sw->set_blend_color( failover->sw, &failover->blend_color );
|
||||
|
|
|
|||
|
|
@ -123,8 +123,9 @@ struct i915_context
|
|||
|
||||
/* The most recent drawing state as set by the driver:
|
||||
*/
|
||||
const struct pipe_blend_state *blend;
|
||||
|
||||
struct pipe_alpha_test_state alpha_test;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clear_color_state clear_color;
|
||||
struct pipe_clip_state clip;
|
||||
|
|
|
|||
|
|
@ -37,17 +37,37 @@
|
|||
|
||||
/* None of this state is actually used for anything yet.
|
||||
*/
|
||||
static void i915_set_blend_state( struct pipe_context *pipe,
|
||||
|
||||
static const struct pipe_blend_state *
|
||||
i915_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
/*struct i915_context *i915 = i915_context(pipe);*/
|
||||
|
||||
struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state));
|
||||
memcpy(new_blend, blend, sizeof(struct pipe_blend_state));
|
||||
|
||||
return new_blend;
|
||||
}
|
||||
|
||||
static void i915_bind_blend_state( struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend )
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
|
||||
i915->blend = *blend;
|
||||
i915->blend = blend;
|
||||
|
||||
i915->dirty |= I915_NEW_BLEND;
|
||||
}
|
||||
|
||||
|
||||
static void i915_delete_blend_state( struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend )
|
||||
{
|
||||
/*struct i915_context *i915 = i915_context(pipe);*/
|
||||
free(blend);
|
||||
}
|
||||
|
||||
static void i915_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color )
|
||||
{
|
||||
|
|
@ -289,9 +309,12 @@ static void i915_set_vertex_element( struct pipe_context *pipe,
|
|||
void
|
||||
i915_init_state_functions( struct i915_context *i915 )
|
||||
{
|
||||
i915->pipe.create_blend_state = i915_create_blend_state;
|
||||
i915->pipe.bind_blend_state = i915_bind_blend_state;
|
||||
i915->pipe.delete_blend_state = i915_delete_blend_state;
|
||||
|
||||
i915->pipe.set_alpha_test_state = i915_set_alpha_test_state;
|
||||
i915->pipe.set_blend_color = i915_set_blend_color;
|
||||
i915->pipe.set_blend_state = i915_set_blend_state;
|
||||
i915->pipe.set_clip_state = i915_set_clip_state;
|
||||
i915->pipe.set_clear_color_state = i915_set_clear_color_state;
|
||||
i915->pipe.set_constant_buffer = i915_set_constant_buffer;
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ static void upload_MODES4( struct i915_context *i915 )
|
|||
{
|
||||
modes4 |= (_3DSTATE_MODES_4_CMD |
|
||||
ENABLE_LOGIC_OP_FUNC |
|
||||
LOGIC_OP_FUNC(i915_translate_logic_op(i915->blend.logicop_func)));
|
||||
LOGIC_OP_FUNC(i915_translate_logic_op(i915->blend->logicop_func)));
|
||||
}
|
||||
|
||||
/* Always, so that we know when state is in-active:
|
||||
|
|
@ -204,13 +204,13 @@ static void upload_IAB( struct i915_context *i915 )
|
|||
unsigned iab = 0;
|
||||
|
||||
{
|
||||
unsigned eqRGB = i915->blend.rgb_func;
|
||||
unsigned srcRGB = i915->blend.rgb_src_factor;
|
||||
unsigned dstRGB = i915->blend.rgb_dst_factor;
|
||||
unsigned eqRGB = i915->blend->rgb_func;
|
||||
unsigned srcRGB = i915->blend->rgb_src_factor;
|
||||
unsigned dstRGB = i915->blend->rgb_dst_factor;
|
||||
|
||||
unsigned eqA = i915->blend.alpha_func;
|
||||
unsigned srcA = i915->blend.alpha_src_factor;
|
||||
unsigned dstA = i915->blend.alpha_dst_factor;
|
||||
unsigned eqA = i915->blend->alpha_func;
|
||||
unsigned srcA = i915->blend->alpha_src_factor;
|
||||
unsigned dstA = i915->blend->alpha_dst_factor;
|
||||
|
||||
/* Special handling for MIN/MAX filter modes handled at
|
||||
* state_tracker level.
|
||||
|
|
|
|||
|
|
@ -145,22 +145,22 @@ static void upload_S5( struct i915_context *i915 )
|
|||
}
|
||||
|
||||
/* I915_NEW_BLEND */
|
||||
if (i915->blend.logicop_enable)
|
||||
if (i915->blend->logicop_enable)
|
||||
LIS5 |= S5_LOGICOP_ENABLE;
|
||||
|
||||
if (i915->blend.dither)
|
||||
if (i915->blend->dither)
|
||||
LIS5 |= S5_COLOR_DITHER_ENABLE;
|
||||
|
||||
if ((i915->blend.colormask & PIPE_MASK_R) == 0)
|
||||
if ((i915->blend->colormask & PIPE_MASK_R) == 0)
|
||||
LIS5 |= S5_WRITEDISABLE_RED;
|
||||
|
||||
if ((i915->blend.colormask & PIPE_MASK_G) == 0)
|
||||
if ((i915->blend->colormask & PIPE_MASK_G) == 0)
|
||||
LIS5 |= S5_WRITEDISABLE_GREEN;
|
||||
|
||||
if ((i915->blend.colormask & PIPE_MASK_B) == 0)
|
||||
if ((i915->blend->colormask & PIPE_MASK_B) == 0)
|
||||
LIS5 |= S5_WRITEDISABLE_BLUE;
|
||||
|
||||
if ((i915->blend.colormask & PIPE_MASK_A) == 0)
|
||||
if ((i915->blend->colormask & PIPE_MASK_A) == 0)
|
||||
LIS5 |= S5_WRITEDISABLE_ALPHA;
|
||||
|
||||
|
||||
|
|
@ -205,11 +205,11 @@ static void upload_S6( struct i915_context *i915 )
|
|||
|
||||
/* I915_NEW_BLEND
|
||||
*/
|
||||
if (i915->blend.blend_enable)
|
||||
if (i915->blend->blend_enable)
|
||||
{
|
||||
unsigned funcRGB = i915->blend.rgb_func;
|
||||
unsigned srcRGB = i915->blend.rgb_src_factor;
|
||||
unsigned dstRGB = i915->blend.rgb_dst_factor;
|
||||
unsigned funcRGB = i915->blend->rgb_func;
|
||||
unsigned srcRGB = i915->blend->rgb_src_factor;
|
||||
unsigned dstRGB = i915->blend->rgb_dst_factor;
|
||||
|
||||
LIS6 |= (S6_CBUF_BLEND_ENABLE |
|
||||
SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) |
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
#include "p_state.h"
|
||||
#include "p_compiler.h"
|
||||
|
||||
|
||||
struct pipe_state_cache;
|
||||
/**
|
||||
* Software pipeline rendering context. Basically a collection of
|
||||
* state setting functions, plus VBO drawing entrypoint.
|
||||
|
|
@ -85,12 +85,16 @@ struct pipe_context {
|
|||
/*
|
||||
* State functions
|
||||
*/
|
||||
const struct pipe_blend_state * (*create_blend_state)(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void (*bind_blend_state)(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void (*delete_blend_state)(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
|
||||
void (*set_alpha_test_state)( struct pipe_context *,
|
||||
const struct pipe_alpha_test_state * );
|
||||
|
||||
void (*set_blend_state)( struct pipe_context *,
|
||||
const struct pipe_blend_state * );
|
||||
|
||||
void (*set_blend_color)( struct pipe_context *,
|
||||
const struct pipe_blend_color * );
|
||||
|
||||
|
|
|
|||
|
|
@ -250,9 +250,12 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
|
|||
softpipe->pipe.max_texture_size = softpipe_max_texture_size;
|
||||
|
||||
/* 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.set_alpha_test_state = softpipe_set_alpha_test_state;
|
||||
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
|
||||
softpipe->pipe.set_blend_state = softpipe_set_blend_state;
|
||||
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
|
||||
softpipe->pipe.set_clear_color_state = softpipe_set_clear_color_state;
|
||||
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;
|
||||
|
|
|
|||
|
|
@ -71,8 +71,9 @@ struct softpipe_context {
|
|||
|
||||
/* The most recent drawing state as set by the driver:
|
||||
*/
|
||||
const struct pipe_blend_state *blend;
|
||||
|
||||
struct pipe_alpha_test_state alpha_test;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clear_color_state clear_color;
|
||||
struct pipe_clip_state clip;
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
|
|||
|
||||
sp->quad.first = sp->quad.output;
|
||||
|
||||
if (sp->blend.colormask != 0xf) {
|
||||
if (sp->blend->colormask != 0xf) {
|
||||
sp->quad.colormask->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.colormask;
|
||||
}
|
||||
|
||||
if (sp->blend.blend_enable) {
|
||||
if (sp->blend->blend_enable) {
|
||||
sp->quad.blend->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.blend;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Compute src/first term RGB
|
||||
*/
|
||||
switch (softpipe->blend.rgb_src_factor) {
|
||||
switch (softpipe->blend->rgb_src_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
VEC4_COPY(source[0], quad->outputs.color[0]); /* R */
|
||||
VEC4_COPY(source[1], quad->outputs.color[1]); /* G */
|
||||
|
|
@ -253,7 +253,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Compute src/first term A
|
||||
*/
|
||||
switch (softpipe->blend.alpha_src_factor) {
|
||||
switch (softpipe->blend->alpha_src_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
VEC4_COPY(source[3], quad->outputs.color[3]); /* A */
|
||||
break;
|
||||
|
|
@ -275,7 +275,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Compute dest/second term RGB
|
||||
*/
|
||||
switch (softpipe->blend.rgb_dst_factor) {
|
||||
switch (softpipe->blend->rgb_dst_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
/* dest = dest * 1 NO-OP, leave dest as-is */
|
||||
break;
|
||||
|
|
@ -301,7 +301,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Compute dest/second term A
|
||||
*/
|
||||
switch (softpipe->blend.alpha_dst_factor) {
|
||||
switch (softpipe->blend->alpha_dst_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
/* dest = dest * 1 NO-OP, leave dest as-is */
|
||||
break;
|
||||
|
|
@ -323,7 +323,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Combine RGB terms
|
||||
*/
|
||||
switch (softpipe->blend.rgb_func) {
|
||||
switch (softpipe->blend->rgb_func) {
|
||||
case PIPE_BLEND_ADD:
|
||||
VEC4_ADD(quad->outputs.color[0], source[0], dest[0]); /* R */
|
||||
VEC4_ADD(quad->outputs.color[1], source[1], dest[1]); /* G */
|
||||
|
|
@ -356,7 +356,7 @@ blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
/*
|
||||
* Combine A terms
|
||||
*/
|
||||
switch (softpipe->blend.alpha_func) {
|
||||
switch (softpipe->blend->alpha_func) {
|
||||
case PIPE_BLEND_ADD:
|
||||
VEC4_ADD(quad->outputs.color[3], source[3], dest[3]); /* A */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -49,19 +49,19 @@ colormask_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
sps->read_quad_f_swz(sps, quad->x0, quad->y0, dest);
|
||||
|
||||
/* R */
|
||||
if (!(softpipe->blend.colormask & PIPE_MASK_R))
|
||||
if (!(softpipe->blend->colormask & PIPE_MASK_R))
|
||||
COPY_4V(quad->outputs.color[0], dest[0]);
|
||||
|
||||
/* G */
|
||||
if (!(softpipe->blend.colormask & PIPE_MASK_G))
|
||||
if (!(softpipe->blend->colormask & PIPE_MASK_G))
|
||||
COPY_4V(quad->outputs.color[1], dest[1]);
|
||||
|
||||
/* B */
|
||||
if (!(softpipe->blend.colormask & PIPE_MASK_B))
|
||||
if (!(softpipe->blend->colormask & PIPE_MASK_B))
|
||||
COPY_4V(quad->outputs.color[2], dest[2]);
|
||||
|
||||
/* A */
|
||||
if (!(softpipe->blend.colormask & PIPE_MASK_A))
|
||||
if (!(softpipe->blend->colormask & PIPE_MASK_A))
|
||||
COPY_4V(quad->outputs.color[3], dest[3]);
|
||||
|
||||
/* pass quad to next stage */
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@
|
|||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
const struct pipe_blend_state *
|
||||
softpipe_create_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void softpipe_bind_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void softpipe_delete_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
|
||||
void softpipe_set_framebuffer_state( struct pipe_context *,
|
||||
const struct pipe_framebuffer_state * );
|
||||
|
|
@ -40,9 +47,6 @@ void softpipe_set_framebuffer_state( struct pipe_context *,
|
|||
void softpipe_set_alpha_test_state( struct pipe_context *,
|
||||
const struct pipe_alpha_test_state * );
|
||||
|
||||
void softpipe_set_blend_state( struct pipe_context *,
|
||||
const struct pipe_blend_state * );
|
||||
|
||||
void softpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color );
|
||||
|
||||
|
|
|
|||
|
|
@ -30,17 +30,32 @@
|
|||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
|
||||
const struct pipe_blend_state *
|
||||
softpipe_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
struct pipe_blend_state *new_blend = malloc(sizeof(struct pipe_blend_state));
|
||||
memcpy(new_blend, blend, sizeof(struct pipe_blend_state));
|
||||
|
||||
void softpipe_set_blend_state( struct pipe_context *pipe,
|
||||
return new_blend;
|
||||
}
|
||||
|
||||
void softpipe_bind_blend_state( struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend )
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
softpipe->blend = *blend;
|
||||
softpipe->blend = blend;
|
||||
|
||||
softpipe->dirty |= SP_NEW_BLEND;
|
||||
}
|
||||
|
||||
void softpipe_delete_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend )
|
||||
{
|
||||
free(blend);
|
||||
}
|
||||
|
||||
|
||||
void softpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color )
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ TGSIDECO_SOURCES = \
|
|||
TGSIMESA_SOURCES = \
|
||||
pipe/tgsi/mesa/mesa_to_tgsi.c
|
||||
|
||||
STATECACHE_SOURCES = \
|
||||
cso_cache/cso_cache.c
|
||||
|
||||
STATETRACKER_SOURCES = \
|
||||
state_tracker/st_atom.c \
|
||||
state_tracker/st_atom_alphatest.c \
|
||||
|
|
@ -373,6 +376,7 @@ SOLO_SOURCES = \
|
|||
$(TGSIEXEC_SOURCES) \
|
||||
$(TGSIDECO_SOURCES) \
|
||||
$(TGSIMESA_SOURCES) \
|
||||
$(STATECACHE_SOURCES) \
|
||||
$(STATETRACKER_SOURCES) \
|
||||
$(TNL_SOURCES) \
|
||||
$(SHADER_SOURCES) \
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "st_atom.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "cso_cache/cso_cache.h"
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -209,10 +210,14 @@ update_blend( struct st_context *st )
|
|||
if (st->ctx->Color.DitherFlag)
|
||||
blend.dither = 1;
|
||||
|
||||
if (memcmp(&blend, &st->state.blend, sizeof(blend)) != 0) {
|
||||
struct pipe_blend_state *real_blend =
|
||||
cso_cached_blend_state(st, &blend);
|
||||
|
||||
if (st->state.blend != real_blend) {
|
||||
/* state has changed */
|
||||
st->state.blend = blend; /* struct copy */
|
||||
st->pipe->set_blend_state(st->pipe, &blend); /* set new state */
|
||||
st->state.blend = real_blend;
|
||||
/* bind new state */
|
||||
st->pipe->bind_blend_state(st->pipe, real_blend);
|
||||
}
|
||||
|
||||
if (memcmp(st->ctx->Color.BlendColor, &st->state.blend_color, 4 * sizeof(GLfloat)) != 0) {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@
|
|||
|
||||
#include "pipe/tgsi/mesa/mesa_to_tgsi.h"
|
||||
|
||||
#include "cso_cache/cso_cache.h"
|
||||
|
||||
#include "vf/vf.h"
|
||||
|
||||
|
||||
|
|
@ -295,7 +297,8 @@ clear_with_quad(GLcontext *ctx,
|
|||
if (st->ctx->Color.DitherFlag)
|
||||
blend.dither = 1;
|
||||
}
|
||||
pipe->set_blend_state(pipe, &blend);
|
||||
const struct pipe_blend_state *state = cso_cached_blend_state(st, &blend);
|
||||
pipe->bind_blend_state(pipe, state);
|
||||
}
|
||||
|
||||
/* depth state: always pass */
|
||||
|
|
@ -390,7 +393,7 @@ clear_with_quad(GLcontext *ctx,
|
|||
|
||||
/* Restore pipe state */
|
||||
pipe->set_alpha_test_state(pipe, &st->state.alpha_test);
|
||||
pipe->set_blend_state(pipe, &st->state.blend);
|
||||
pipe->bind_blend_state(pipe, st->state.blend);
|
||||
pipe->set_depth_state(pipe, &st->state.depth);
|
||||
pipe->set_fs_state(pipe, &st->state.fs);
|
||||
pipe->set_vs_state(pipe, &st->state.vs);
|
||||
|
|
|
|||
|
|
@ -474,8 +474,8 @@ static GLboolean
|
|||
any_fragment_ops(const struct st_context *st)
|
||||
{
|
||||
if (st->state.alpha_test.enabled ||
|
||||
st->state.blend.blend_enable ||
|
||||
st->state.blend.logicop_enable ||
|
||||
st->state.blend->blend_enable ||
|
||||
st->state.blend->logicop_enable ||
|
||||
st->state.depth.enabled)
|
||||
/* XXX more checks */
|
||||
return GL_TRUE;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "st_program.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/draw/draw_context.h"
|
||||
#include "cso_cache/cso_cache.h"
|
||||
|
||||
|
||||
void st_invalidate_state(GLcontext * ctx, GLuint new_state)
|
||||
|
|
@ -71,6 +72,8 @@ struct st_context *st_create_context( GLcontext *ctx,
|
|||
st->dirty.mesa = ~0;
|
||||
st->dirty.st = ~0;
|
||||
|
||||
st->cache = cso_cache_create();
|
||||
|
||||
st_init_atoms( st );
|
||||
st_init_draw( st );
|
||||
|
||||
|
|
@ -112,6 +115,7 @@ void st_destroy_context( struct st_context *st )
|
|||
/*st_destroy_cb_teximage( st );*/
|
||||
st_destroy_cb_texture( st );
|
||||
#endif
|
||||
cso_cache_destroy( st->cache );
|
||||
|
||||
st->pipe->destroy( st->pipe );
|
||||
FREE( st );
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ struct st_texture_image;
|
|||
struct st_fragment_program;
|
||||
struct draw_context;
|
||||
struct draw_stage;
|
||||
|
||||
struct cso_cache;
|
||||
|
||||
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
|
||||
#define ST_NEW_FRAGMENT_PROGRAM 0x2
|
||||
|
|
@ -74,8 +74,9 @@ struct st_context
|
|||
* though, we just shove random objects across the interface.
|
||||
*/
|
||||
struct {
|
||||
const struct pipe_blend_state *blend;
|
||||
|
||||
struct pipe_alpha_test_state alpha_test;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_clear_color_state clear_color;
|
||||
struct pipe_clip_state clip;
|
||||
|
|
@ -122,6 +123,8 @@ struct st_context
|
|||
struct st_fragment_program *fp;
|
||||
|
||||
struct pipe_buffer_handle *default_attrib_buffer;
|
||||
|
||||
struct cso_cache *cache;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue