1
0
Fork 0

cogl-pipeline-layer: Use CoglTextureType instead of GL target enum

Instead of storing the GLenum for the target of the last used texture
for a layer it now stores the CoglTextureType instead. The state name
has been renamed to 'texture type' instead of 'texture target'.
Previously the default pipeline layer would store 0 here to represent
that there is no texture. This has been changed to store
COGL_TEXTURE_TYPE_2D instead which means that all pipeline layers
always have a valid value for the texture type. Any places that were
previously fetching the texture from a layer to determine the target
(for example when generating shaders or when enabling a particular
texture target) now use the texture type instead. This means they will
work even for layers that don't have a texture.

This also changes it so that when binding a fallback texture instead
of always using a 2D texture it will now use the default texture
corresponding to the texture type of the layer. That way when the
generated shader tries to do a texture lookup for that type of texture
it will get a valid texture object. To make this work the patch adds a
default texture for 3D textures to the context and also makes the
default rectangle texture actually be a rectangle texture instead of
using a 2D texture.

Reviewed-by: Robert Bragg <robert@linux.intel.com>
This commit is contained in:
Neil Roberts 2012-02-09 12:52:45 +00:00
parent 8012eee31f
commit b96e6900f5
11 changed files with 205 additions and 173 deletions

View file

@ -126,6 +126,7 @@ struct _CoglContext
/* Textures */ /* Textures */
CoglHandle default_gl_texture_2d_tex; CoglHandle default_gl_texture_2d_tex;
CoglHandle default_gl_texture_3d_tex;
CoglHandle default_gl_texture_rect_tex; CoglHandle default_gl_texture_rect_tex;
/* Central list of all framebuffers so all journals can be flushed /* Central list of all framebuffers so all journals can be flushed

View file

@ -38,6 +38,9 @@
#include "cogl-renderer-private.h" #include "cogl-renderer-private.h"
#include "cogl-journal-private.h" #include "cogl-journal-private.h"
#include "cogl-texture-private.h" #include "cogl-texture-private.h"
#include "cogl-texture-2d-private.h"
#include "cogl-texture-3d-private.h"
#include "cogl-texture-rectangle-private.h"
#include "cogl-pipeline-private.h" #include "cogl-pipeline-private.h"
#include "cogl-pipeline-opengl-private.h" #include "cogl-pipeline-opengl-private.h"
#include "cogl-framebuffer-private.h" #include "cogl-framebuffer-private.h"
@ -130,6 +133,7 @@ cogl_context_new (CoglDisplay *display,
{ {
CoglContext *context; CoglContext *context;
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 }; GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
CoglBitmap *default_texture_bitmap;
const CoglWinsysVtable *winsys; const CoglWinsysVtable *winsys;
int i; int i;
@ -275,6 +279,7 @@ cogl_context_new (CoglDisplay *display,
context->legacy_state_set = 0; context->legacy_state_set = 0;
context->default_gl_texture_2d_tex = NULL; context->default_gl_texture_2d_tex = NULL;
context->default_gl_texture_3d_tex = NULL;
context->default_gl_texture_rect_tex = NULL; context->default_gl_texture_rect_tex = NULL;
context->framebuffers = NULL; context->framebuffers = NULL;
@ -376,25 +381,36 @@ cogl_context_new (CoglDisplay *display,
_cogl_matrix_stack_init_cache (&_context->builtin_flushed_projection); _cogl_matrix_stack_init_cache (&_context->builtin_flushed_projection);
_cogl_matrix_stack_init_cache (&_context->builtin_flushed_modelview); _cogl_matrix_stack_init_cache (&_context->builtin_flushed_modelview);
default_texture_bitmap =
_cogl_bitmap_new_from_data (default_texture_data,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
1, 1, /* width/height */
4, /* rowstride */
NULL, /* destroy function */
NULL /* destroy function data */);
/* Create default textures used for fall backs */ /* Create default textures used for fall backs */
context->default_gl_texture_2d_tex = context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */ _cogl_texture_2d_new_from_bitmap (default_texture_bitmap,
1, /* height */ COGL_TEXTURE_NONE,
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */
/* internal format */ /* internal format */
COGL_PIXEL_FORMAT_RGBA_8888_PRE, COGL_PIXEL_FORMAT_RGBA_8888_PRE,
0, /* auto calc row stride */ NULL);
default_texture_data); /* If 3D or rectangle textures aren't supported then these should
just silently return NULL */
context->default_gl_texture_3d_tex =
_cogl_texture_3d_new_from_bitmap (default_texture_bitmap,
1, /* height */
1, /* depth */
COGL_TEXTURE_NONE,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
NULL);
context->default_gl_texture_rect_tex = context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */ _cogl_texture_rectangle_new_from_bitmap (default_texture_bitmap,
1, /* height */ COGL_TEXTURE_NONE,
COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_RGBA_8888_PRE);
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* data format */
/* internal format */ cogl_object_unref (default_texture_bitmap);
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
0, /* auto calc row stride */
default_texture_data);
cogl_push_source (context->opaque_color_pipeline); cogl_push_source (context->opaque_color_pipeline);
_cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0); _cogl_pipeline_flush_gl_state (context->opaque_color_pipeline, FALSE, 0);
@ -433,6 +449,8 @@ _cogl_context_free (CoglContext *context)
if (context->default_gl_texture_2d_tex) if (context->default_gl_texture_2d_tex)
cogl_object_unref (context->default_gl_texture_2d_tex); cogl_object_unref (context->default_gl_texture_2d_tex);
if (context->default_gl_texture_3d_tex)
cogl_object_unref (context->default_gl_texture_3d_tex);
if (context->default_gl_texture_rect_tex) if (context->default_gl_texture_rect_tex)
cogl_object_unref (context->default_gl_texture_rect_tex); cogl_object_unref (context->default_gl_texture_rect_tex);

View file

@ -291,26 +291,31 @@ _cogl_pipeline_fragend_arbfp_start (CoglPipeline *pipeline,
} }
static const char * static const char *
gl_target_to_arbfp_string (GLenum gl_target) texture_type_to_arbfp_string (CoglTextureType texture_type)
{ {
if (gl_target == GL_TEXTURE_1D) switch (texture_type)
{
#if 0 /* TODO */
case COGL_TEXTURE_TYPE_1D:
return "1D"; return "1D";
else if (gl_target == GL_TEXTURE_2D)
return "2D";
#ifdef GL_ARB_texture_rectangle
else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
return "RECT";
#endif #endif
else if (gl_target == GL_TEXTURE_3D) case COGL_TEXTURE_TYPE_2D:
return "2D";
case COGL_TEXTURE_TYPE_3D:
return "3D"; return "3D";
else case COGL_TEXTURE_TYPE_RECTANGLE:
return "RECT";
}
g_warn_if_reached ();
return "2D"; return "2D";
} }
static void static void
setup_texture_source (CoglPipelineShaderState *shader_state, setup_texture_source (CoglPipelineShaderState *shader_state,
int unit_index, int unit_index,
GLenum gl_target) CoglTextureType texture_type)
{ {
if (!shader_state->unit_state[unit_index].sampled) if (!shader_state->unit_state[unit_index].sampled)
{ {
@ -329,7 +334,7 @@ setup_texture_source (CoglPipelineShaderState *shader_state,
unit_index, unit_index,
unit_index, unit_index,
unit_index, unit_index,
gl_target_to_arbfp_string (gl_target)); texture_type_to_arbfp_string (texture_type));
shader_state->unit_state[unit_index].sampled = TRUE; shader_state->unit_state[unit_index].sampled = TRUE;
} }
} }
@ -349,7 +354,7 @@ typedef struct _CoglPipelineFragendARBfpArg
/* for type = TEXTURE */ /* for type = TEXTURE */
int texture_unit; int texture_unit;
GLenum texture_target; CoglTextureType texture_type;
/* for type = CONSTANT */ /* for type = CONSTANT */
int constant_id; int constant_id;
@ -392,8 +397,6 @@ setup_arg (CoglPipeline *pipeline,
{ {
CoglPipelineShaderState *shader_state = get_shader_state (pipeline); CoglPipelineShaderState *shader_state = get_shader_state (pipeline);
static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" }; static const char *tmp_name[3] = { "tmp0", "tmp1", "tmp2" };
GLenum gl_target;
CoglHandle texture;
switch (src) switch (src)
{ {
@ -401,12 +404,9 @@ setup_arg (CoglPipeline *pipeline,
arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE;
arg->name = "texel%d"; arg->name = "texel%d";
arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer); arg->texture_unit = _cogl_pipeline_layer_get_unit_index (layer);
texture = _cogl_pipeline_layer_get_texture (layer); setup_texture_source (shader_state,
if (texture) arg->texture_unit,
cogl_texture_get_gl_texture (texture, NULL, &gl_target); _cogl_pipeline_layer_get_texture_type (layer));
else
gl_target = GL_TEXTURE_2D;
setup_texture_source (shader_state, arg->texture_unit, gl_target);
break; break;
case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT: case COGL_PIPELINE_COMBINE_SOURCE_CONSTANT:
{ {
@ -437,12 +437,12 @@ setup_arg (CoglPipeline *pipeline,
arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE; arg->type = COGL_PIPELINE_FRAGEND_ARBFP_ARG_TYPE_TEXTURE;
arg->name = "texture[%d]"; arg->name = "texture[%d]";
arg->texture_unit = src - GL_TEXTURE0; arg->texture_unit = src - GL_TEXTURE0;
texture = _cogl_pipeline_layer_get_texture (layer); /* FIXME: Is this right? Shouldn't it be using the texture type
if (texture) of the layer for the given unit, not the type of the layer
cogl_texture_get_gl_texture (texture, NULL, &gl_target); we're generating for? */
else setup_texture_source (shader_state,
gl_target = GL_TEXTURE_2D; arg->texture_unit,
setup_texture_source (shader_state, arg->texture_unit, gl_target); _cogl_pipeline_layer_get_texture_type (layer));
} }
arg->swizzle = ""; arg->swizzle = "";

View file

@ -50,6 +50,10 @@
#include <glib/gprintf.h> #include <glib/gprintf.h>
#include <string.h> #include <string.h>
#ifndef GL_TEXTURE_RECTANGLE_ARB
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
#endif
const CoglPipelineFragend _cogl_pipeline_fixed_fragend; const CoglPipelineFragend _cogl_pipeline_fixed_fragend;
static void static void
@ -149,20 +153,27 @@ _cogl_pipeline_fragend_fixed_add_layer (CoglPipeline *pipeline,
return TRUE; return TRUE;
} }
/* Handle enabling or disabling the right texture target */ /* Handle enabling or disabling the right texture type */
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET) if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE)
{ {
CoglPipelineLayer *tex_authority = CoglTextureType texture_type =
_cogl_pipeline_layer_get_authority (layer, _cogl_pipeline_layer_get_texture_type (layer);
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA); GLenum gl_target;
CoglPipelineLayer *target_authority =
_cogl_pipeline_layer_get_authority (layer, switch (texture_type)
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET); {
/* XXX: currently layers with no associated texture fallback to case COGL_TEXTURE_TYPE_2D:
* using ctx->default_gl_texture_2d_tex so they have a texture gl_target = GL_TEXTURE_2D;
* target of GL_TEXTURE_2D */ break;
GLenum gl_target =
tex_authority->texture ? target_authority->target : GL_TEXTURE_2D; case COGL_TEXTURE_TYPE_3D:
gl_target = GL_TEXTURE_3D;
break;
case COGL_TEXTURE_TYPE_RECTANGLE:
gl_target = GL_TEXTURE_RECTANGLE_ARB;
break;
}
_cogl_set_active_texture_unit (unit_index); _cogl_set_active_texture_unit (unit_index);

View file

@ -422,48 +422,33 @@ ensure_texture_lookup_generated (CoglPipelineShaderState *shader_state,
to be replaced */ to be replaced */
if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP)) if (!has_replace_hook (layer, COGL_SNIPPET_HOOK_TEXTURE_LOOKUP))
{ {
CoglHandle texture = _cogl_pipeline_layer_get_texture (layer); CoglTextureType texture_type =
_cogl_pipeline_layer_get_texture_type (layer);
const char *target_string, *tex_coord_swizzle; const char *target_string, *tex_coord_swizzle;
if (texture == NULL) switch (texture_type)
{ {
target_string = "2D"; #if 0 /* TODO */
tex_coord_swizzle = "st"; case COGL_TEXTURE_TYPE_1D:
}
else
{
GLenum gl_target;
cogl_texture_get_gl_texture (texture, NULL, &gl_target);
switch (gl_target)
{
#ifdef HAVE_COGL_GL
case GL_TEXTURE_1D:
target_string = "1D"; target_string = "1D";
tex_coord_swizzle = "s"; tex_coord_swizzle = "s";
break; break;
#endif #endif
case GL_TEXTURE_2D: case COGL_TEXTURE_TYPE_2D:
target_string = "2D"; target_string = "2D";
tex_coord_swizzle = "st"; tex_coord_swizzle = "st";
break; break;
#ifdef GL_ARB_texture_rectangle case COGL_TEXTURE_TYPE_3D:
case GL_TEXTURE_RECTANGLE_ARB:
target_string = "2DRect";
tex_coord_swizzle = "st";
break;
#endif
case GL_TEXTURE_3D:
target_string = "3D"; target_string = "3D";
tex_coord_swizzle = "stp"; tex_coord_swizzle = "stp";
break; break;
default: case COGL_TEXTURE_TYPE_RECTANGLE:
g_assert_not_reached (); target_string = "2DRect";
} tex_coord_swizzle = "st";
break;
} }
/* Create a sampler uniform */ /* Create a sampler uniform */

View file

@ -71,7 +71,7 @@ typedef enum
{ {
/* sparse state */ /* sparse state */
COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX, COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX, COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX,
COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX, COGL_PIPELINE_LAYER_STATE_WRAP_MODES_INDEX,
@ -99,8 +99,8 @@ typedef enum
{ {
COGL_PIPELINE_LAYER_STATE_UNIT = COGL_PIPELINE_LAYER_STATE_UNIT =
1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX, 1L<<COGL_PIPELINE_LAYER_STATE_UNIT_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET = COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE =
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX, 1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX,
COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA =
1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX, 1L<<COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX,
COGL_PIPELINE_LAYER_STATE_FILTERS = COGL_PIPELINE_LAYER_STATE_FILTERS =
@ -259,7 +259,11 @@ struct _CoglPipelineLayer
/* The texture for this layer, or NULL for an empty /* The texture for this layer, or NULL for an empty
* layer */ * layer */
CoglTexture *texture; CoglTexture *texture;
GLenum target; /* The type of the texture. This is always set even if the texture
is NULL and it will be used to determine what type of texture
lookups to use in any shaders generated by the pipeline
backends. */
CoglTextureType texture_type;
CoglPipelineFilter mag_filter; CoglPipelineFilter mag_filter;
CoglPipelineFilter min_filter; CoglPipelineFilter min_filter;
@ -363,6 +367,9 @@ _cogl_pipeline_layer_get_texture (CoglPipelineLayer *layer);
CoglTexture * CoglTexture *
_cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer); _cogl_pipeline_layer_get_texture_real (CoglPipelineLayer *layer);
CoglTextureType
_cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer);
CoglPipelineFilter CoglPipelineFilter
_cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer); _cogl_pipeline_layer_get_min_filter (CoglPipelineLayer *layer);

View file

@ -45,7 +45,7 @@ _cogl_pipeline_get_layer_mag_filter (CoglPipeline *pipeline,
int layer_index); int layer_index);
gboolean gboolean
_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0, _cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
CoglPipelineLayer *authority1, CoglPipelineLayer *authority1,
CoglPipelineEvalFlags flags); CoglPipelineEvalFlags flags);
@ -92,7 +92,7 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
CoglPipelineHashState *state); CoglPipelineHashState *state);
void void
_cogl_pipeline_layer_hash_texture_target_state (CoglPipelineLayer *authority, _cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
CoglPipelineLayer **authorities, CoglPipelineLayer **authorities,
CoglPipelineHashState *state); CoglPipelineHashState *state);

View file

@ -129,12 +129,22 @@ cogl_pipeline_get_layer_texture (CoglPipeline *pipeline,
return _cogl_pipeline_layer_get_texture (layer); return _cogl_pipeline_layer_get_texture (layer);
} }
static void CoglTextureType
_cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline, _cogl_pipeline_layer_get_texture_type (CoglPipelineLayer *layer)
int layer_index,
GLenum target)
{ {
CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET; CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer,
COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE);
return authority->texture_type;
}
static void
_cogl_pipeline_set_layer_texture_type (CoglPipeline *pipeline,
int layer_index,
CoglTextureType texture_type)
{
CoglPipelineLayerState change = COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE;
CoglPipelineLayer *layer; CoglPipelineLayer *layer;
CoglPipelineLayer *authority; CoglPipelineLayer *authority;
CoglPipelineLayer *new; CoglPipelineLayer *new;
@ -151,7 +161,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
* state we want to change */ * state we want to change */
authority = _cogl_pipeline_layer_get_authority (layer, change); authority = _cogl_pipeline_layer_get_authority (layer, change);
if (target == authority->target) if (texture_type == authority->texture_type)
return; return;
new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change); new = _cogl_pipeline_layer_pre_change_notify (pipeline, layer, change);
@ -170,7 +180,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
CoglPipelineLayer *old_authority = CoglPipelineLayer *old_authority =
_cogl_pipeline_layer_get_authority (parent, change); _cogl_pipeline_layer_get_authority (parent, change);
if (old_authority->target == target) if (old_authority->texture_type == texture_type)
{ {
layer->differences &= ~change; layer->differences &= ~change;
@ -183,7 +193,7 @@ _cogl_pipeline_set_layer_texture_target (CoglPipeline *pipeline,
} }
} }
layer->target = target; layer->texture_type = texture_type;
/* If we weren't previously the authority on this state then we need /* If we weren't previously the authority on this state then we need
* to extended our differences mask and so it's possible that some * to extended our differences mask and so it's possible that some
@ -279,30 +289,13 @@ changed:
_cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS); _cogl_pipeline_update_blend_enable (pipeline, COGL_PIPELINE_STATE_LAYERS);
} }
/* A convenience for querying the target of a given texture that
* notably returns 0 for NULL textures - so we can say that a layer
* with no associated CoglTexture will have a texture target of 0.
*/
static GLenum
get_texture_target (CoglTexture *texture)
{
GLuint ignore_handle;
GLenum gl_target;
_COGL_RETURN_VAL_IF_FAIL (texture, 0);
cogl_texture_get_gl_texture (texture, &ignore_handle, &gl_target);
return gl_target;
}
void void
cogl_pipeline_set_layer_texture (CoglPipeline *pipeline, cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
int layer_index, int layer_index,
CoglTexture *texture) CoglTexture *texture)
{ {
/* For the convenience of fragend code we separate texture state /* For the convenience of fragend code we separate texture state
* into the "target" and the "data", and setting a layer texture * into the "type" and the "data", and setting a layer texture
* updates both of these properties. * updates both of these properties.
* *
* One example for why this is helpful is that the fragends may * One example for why this is helpful is that the fragends may
@ -311,17 +304,22 @@ cogl_pipeline_set_layer_texture (CoglPipeline *pipeline,
* For the sake of determining if pipelines have equivalent fragment * For the sake of determining if pipelines have equivalent fragment
* processing state we don't need to compare that the same * processing state we don't need to compare that the same
* underlying texture objects are referenced by the pipelines but we * underlying texture objects are referenced by the pipelines but we
* do need to see if they use the same texture targets. Making this * do need to see if they use the same texture types. Making this
* distinction is much simpler if they are in different state * distinction is much simpler if they are in different state
* groups. * groups.
* *
* Note: if a NULL texture is set then we leave the target unchanged * Note: if a NULL texture is set then we leave the type unchanged
* so we can avoid needlessly invalidating any associated fragment * so we can avoid needlessly invalidating any associated fragment
* program. * program.
*/ */
if (texture) if (texture)
_cogl_pipeline_set_layer_texture_target (pipeline, layer_index, {
get_texture_target (texture)); CoglTextureType texture_type =
_cogl_texture_get_type (texture);
_cogl_pipeline_set_layer_texture_type (pipeline,
layer_index,
texture_type);
}
_cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture); _cogl_pipeline_set_layer_texture_data (pipeline, layer_index, texture);
} }
@ -867,11 +865,11 @@ cogl_pipeline_add_layer_snippet (CoglPipeline *pipeline,
} }
gboolean gboolean
_cogl_pipeline_layer_texture_target_equal (CoglPipelineLayer *authority0, _cogl_pipeline_layer_texture_type_equal (CoglPipelineLayer *authority0,
CoglPipelineLayer *authority1, CoglPipelineLayer *authority1,
CoglPipelineEvalFlags flags) CoglPipelineEvalFlags flags)
{ {
return authority0->target == authority1->target; return authority0->texture_type == authority1->texture_type;
} }
gboolean gboolean
@ -1613,14 +1611,15 @@ _cogl_pipeline_layer_hash_unit_state (CoglPipelineLayer *authority,
} }
void void
_cogl_pipeline_layer_hash_texture_target_state (CoglPipelineLayer *authority, _cogl_pipeline_layer_hash_texture_type_state (CoglPipelineLayer *authority,
CoglPipelineLayer **authorities, CoglPipelineLayer **authorities,
CoglPipelineHashState *state) CoglPipelineHashState *state)
{ {
GLenum gl_target = authority->target; CoglTextureType texture_type = authority->texture_type;
state->hash = state->hash = _cogl_util_one_at_a_time_hash (state->hash,
_cogl_util_one_at_a_time_hash (state->hash, &gl_target, sizeof (gl_target)); &texture_type,
sizeof (texture_type));
} }
void void

View file

@ -165,7 +165,7 @@ _cogl_pipeline_layer_init_multi_property_sparse_state (
/* XXX: avoid using a default: label so we get a warning if we /* XXX: avoid using a default: label so we get a warning if we
* don't explicitly handle a newly defined state-group here. */ * don't explicitly handle a newly defined state-group here. */
case COGL_PIPELINE_LAYER_STATE_UNIT: case COGL_PIPELINE_LAYER_STATE_UNIT:
case COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET: case COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE:
case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA: case COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA:
case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS: case COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS:
case COGL_PIPELINE_LAYER_STATE_USER_MATRIX: case COGL_PIPELINE_LAYER_STATE_USER_MATRIX:
@ -544,11 +544,11 @@ _cogl_pipeline_layer_equal (CoglPipelineLayer *layer0,
layers_difference, layers_difference,
authorities1); authorities1);
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET) if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE)
{ {
CoglPipelineLayerStateIndex state_index = CoglPipelineLayerStateIndex state_index =
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX; COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX;
if (!_cogl_pipeline_layer_texture_target_equal (authorities0[state_index], if (!_cogl_pipeline_layer_texture_type_equal (authorities0[state_index],
authorities1[state_index], authorities1[state_index],
flags)) flags))
return FALSE; return FALSE;
@ -655,7 +655,7 @@ _cogl_pipeline_init_default_layers (void)
layer->unit_index = 0; layer->unit_index = 0;
layer->texture = NULL; layer->texture = NULL;
layer->target = 0; layer->texture_type = COGL_TEXTURE_TYPE_2D;
layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR; layer->mag_filter = COGL_PIPELINE_FILTER_LINEAR;
layer->min_filter = COGL_PIPELINE_FILTER_LINEAR; layer->min_filter = COGL_PIPELINE_FILTER_LINEAR;

View file

@ -779,16 +779,23 @@ flush_layers_common_gl_state_cb (CoglPipelineLayer *layer, void *user_data)
if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA) if (layers_difference & COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA)
{ {
unsigned long state = COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA; CoglTexture *texture = _cogl_pipeline_layer_get_texture_real (layer);
CoglPipelineLayer *authority =
_cogl_pipeline_layer_get_authority (layer, state);
CoglTexture *texture;
GLuint gl_texture; GLuint gl_texture;
GLenum gl_target; GLenum gl_target;
texture = (authority->texture == NULL ? if (texture == NULL)
ctx->default_gl_texture_2d_tex : switch (_cogl_pipeline_layer_get_texture_type (layer))
authority->texture); {
case COGL_TEXTURE_TYPE_2D:
texture = ctx->default_gl_texture_2d_tex;
break;
case COGL_TEXTURE_TYPE_3D:
texture = ctx->default_gl_texture_3d_tex;
break;
case COGL_TEXTURE_TYPE_RECTANGLE:
texture = ctx->default_gl_texture_rect_tex;
break;
}
cogl_texture_get_gl_texture (texture, cogl_texture_get_gl_texture (texture,
&gl_texture, &gl_texture,

View file

@ -1870,8 +1870,8 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
{ {
CoglPipelineFallbackState *state = user_data; CoglPipelineFallbackState *state = user_data;
CoglPipeline *pipeline = state->pipeline; CoglPipeline *pipeline = state->pipeline;
CoglHandle texture = _cogl_pipeline_layer_get_texture (layer); CoglTextureType texture_type = _cogl_pipeline_layer_get_texture_type (layer);
GLenum gl_target; CoglTexture *texture = NULL;
COGL_STATIC_COUNTER (layer_fallback_counter, COGL_STATIC_COUNTER (layer_fallback_counter,
"layer fallback counter", "layer fallback counter",
"Increments each time a layer's texture is " "Increments each time a layer's texture is "
@ -1885,18 +1885,22 @@ fallback_layer_cb (CoglPipelineLayer *layer, void *user_data)
COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter); COGL_COUNTER_INC (_cogl_uprof_context, layer_fallback_counter);
if (G_LIKELY (texture != NULL)) switch (texture_type)
cogl_texture_get_gl_texture (texture, NULL, &gl_target); {
else case COGL_TEXTURE_TYPE_2D:
gl_target = GL_TEXTURE_2D;
if (gl_target == GL_TEXTURE_2D)
texture = ctx->default_gl_texture_2d_tex; texture = ctx->default_gl_texture_2d_tex;
#ifdef HAVE_COGL_GL break;
else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
case COGL_TEXTURE_TYPE_3D:
texture = ctx->default_gl_texture_3d_tex;
break;
case COGL_TEXTURE_TYPE_RECTANGLE:
texture = ctx->default_gl_texture_rect_tex; texture = ctx->default_gl_texture_rect_tex;
#endif break;
else }
if (texture == NULL)
{ {
g_warning ("We don't have a fallback texture we can use to fill " g_warning ("We don't have a fallback texture we can use to fill "
"in for an invalid pipeline layer, since it was " "in for an invalid pipeline layer, since it was "
@ -2605,8 +2609,8 @@ _cogl_pipeline_init_layer_state_hash_functions (void)
CoglPipelineLayerStateIndex _index; CoglPipelineLayerStateIndex _index;
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] = layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_UNIT_INDEX] =
_cogl_pipeline_layer_hash_unit_state; _cogl_pipeline_layer_hash_unit_state;
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET_INDEX] = layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE_INDEX] =
_cogl_pipeline_layer_hash_texture_target_state; _cogl_pipeline_layer_hash_texture_type_state;
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] = layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_TEXTURE_DATA_INDEX] =
_cogl_pipeline_layer_hash_texture_data_state; _cogl_pipeline_layer_hash_texture_data_state;
layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX] = layer_state_hash_functions[COGL_PIPELINE_LAYER_STATE_FILTERS_INDEX] =
@ -2912,7 +2916,7 @@ _cogl_pipeline_get_layer_state_for_fragment_codegen (CoglContext *context)
{ {
CoglPipelineLayerState state = CoglPipelineLayerState state =
(COGL_PIPELINE_LAYER_STATE_COMBINE | (COGL_PIPELINE_LAYER_STATE_COMBINE |
COGL_PIPELINE_LAYER_STATE_TEXTURE_TARGET | COGL_PIPELINE_LAYER_STATE_TEXTURE_TYPE |
COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS | COGL_PIPELINE_LAYER_STATE_POINT_SPRITE_COORDS |
COGL_PIPELINE_LAYER_STATE_UNIT | COGL_PIPELINE_LAYER_STATE_UNIT |
COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS); COGL_PIPELINE_LAYER_STATE_FRAGMENT_SNIPPETS);