mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-26 17:10:11 +01:00
llvmpipe: Fork softpipe for experimentation with llvm.
This commit is contained in:
parent
1814d6b49c
commit
946f432a08
57 changed files with 11082 additions and 2 deletions
|
|
@ -32,7 +32,7 @@ import common
|
|||
default_statetrackers = 'mesa'
|
||||
|
||||
if common.default_platform in ('linux', 'freebsd', 'darwin'):
|
||||
default_drivers = 'softpipe,failover,i915simple,trace,identity'
|
||||
default_drivers = 'softpipe,failover,i915simple,trace,identity,llvmpipe'
|
||||
default_winsys = 'xlib'
|
||||
elif common.default_platform in ('winddk',):
|
||||
default_drivers = 'softpipe,i915simple,trace,identity'
|
||||
|
|
@ -46,7 +46,7 @@ common.AddOptions(opts)
|
|||
opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers,
|
||||
['mesa', 'python', 'xorg']))
|
||||
opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers,
|
||||
['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity']))
|
||||
['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity', 'llvmpipe']))
|
||||
opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys,
|
||||
['xlib', 'intel', 'gdi', 'radeon']))
|
||||
|
||||
|
|
|
|||
44
src/gallium/drivers/llvmpipe/Makefile
Normal file
44
src/gallium/drivers/llvmpipe/Makefile
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBNAME = llvmpipe
|
||||
|
||||
C_SOURCES = \
|
||||
lp_fs_exec.c \
|
||||
lp_fs_sse.c \
|
||||
lp_fs_llvm.c \
|
||||
lp_clear.c \
|
||||
lp_flush.c \
|
||||
lp_query.c \
|
||||
lp_context.c \
|
||||
lp_draw_arrays.c \
|
||||
lp_prim_setup.c \
|
||||
lp_prim_vbuf.c \
|
||||
lp_quad_pipe.c \
|
||||
lp_quad_alpha_test.c \
|
||||
lp_quad_blend.c \
|
||||
lp_quad_colormask.c \
|
||||
lp_quad_coverage.c \
|
||||
lp_quad_depth_test.c \
|
||||
lp_quad_earlyz.c \
|
||||
lp_quad_fs.c \
|
||||
lp_quad_occlusion.c \
|
||||
lp_quad_output.c \
|
||||
lp_quad_stencil.c \
|
||||
lp_quad_stipple.c \
|
||||
lp_screen.c \
|
||||
lp_setup.c \
|
||||
lp_state_blend.c \
|
||||
lp_state_clip.c \
|
||||
lp_state_derived.c \
|
||||
lp_state_fs.c \
|
||||
lp_state_sampler.c \
|
||||
lp_state_rasterizer.c \
|
||||
lp_state_surface.c \
|
||||
lp_state_vertex.c \
|
||||
lp_texture.c \
|
||||
lp_tex_sample.c \
|
||||
lp_tile_cache.c \
|
||||
lp_surface.c
|
||||
|
||||
include ../../Makefile.template
|
||||
46
src/gallium/drivers/llvmpipe/SConscript
Normal file
46
src/gallium/drivers/llvmpipe/SConscript
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
Import('*')
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
llvmpipe = env.ConvenienceLibrary(
|
||||
target = 'llvmpipe',
|
||||
source = [
|
||||
'lp_fs_exec.c',
|
||||
'lp_fs_sse.c',
|
||||
'lp_fs_llvm.c',
|
||||
'lp_clear.c',
|
||||
'lp_context.c',
|
||||
'lp_draw_arrays.c',
|
||||
'lp_flush.c',
|
||||
'lp_prim_setup.c',
|
||||
'lp_prim_vbuf.c',
|
||||
'lp_setup.c',
|
||||
'lp_quad_alpha_test.c',
|
||||
'lp_quad_blend.c',
|
||||
'lp_quad_pipe.c',
|
||||
'lp_quad_colormask.c',
|
||||
'lp_quad_coverage.c',
|
||||
'lp_quad_depth_test.c',
|
||||
'lp_quad_earlyz.c',
|
||||
'lp_quad_fs.c',
|
||||
'lp_quad_occlusion.c',
|
||||
'lp_quad_output.c',
|
||||
'lp_quad_stencil.c',
|
||||
'lp_quad_stipple.c',
|
||||
'lp_query.c',
|
||||
'lp_screen.c',
|
||||
'lp_state_blend.c',
|
||||
'lp_state_clip.c',
|
||||
'lp_state_derived.c',
|
||||
'lp_state_fs.c',
|
||||
'lp_state_rasterizer.c',
|
||||
'lp_state_sampler.c',
|
||||
'lp_state_surface.c',
|
||||
'lp_state_vertex.c',
|
||||
'lp_surface.c',
|
||||
'lp_tex_sample.c',
|
||||
'lp_texture.c',
|
||||
'lp_tile_cache.c',
|
||||
])
|
||||
|
||||
Export('softpipe')
|
||||
89
src/gallium/drivers/llvmpipe/lp_clear.c
Normal file
89
src/gallium/drivers/llvmpipe/lp_clear.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
* Copyright 2009 VMware, Inc. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Brian Paul
|
||||
* Michel Dänzer
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include "lp_clear.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
|
||||
/**
|
||||
* Clear the given buffers to the specified values.
|
||||
* No masking, no scissor (clear entire buffer).
|
||||
*/
|
||||
void
|
||||
llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
|
||||
double depth, unsigned stencil)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
unsigned cv;
|
||||
uint i;
|
||||
|
||||
if (llvmpipe->no_rast)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
llvmpipe_update_derived(llvmpipe); /* not needed?? */
|
||||
#endif
|
||||
|
||||
if (buffers & PIPE_CLEAR_COLOR) {
|
||||
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
|
||||
struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i];
|
||||
|
||||
util_pack_color(rgba, ps->format, &cv);
|
||||
lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
|
||||
|
||||
#if !TILE_CLEAR_OPTIMIZATION
|
||||
/* non-cached surface */
|
||||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
|
||||
static const float zero[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
|
||||
struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf;
|
||||
|
||||
cv = util_pack_z_stencil(ps->format, depth, stencil);
|
||||
lp_tile_cache_clear(llvmpipe->zsbuf_cache, zero, cv);
|
||||
|
||||
#if !TILE_CLEAR_OPTIMIZATION
|
||||
/* non-cached surface */
|
||||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
43
src/gallium/drivers/llvmpipe/lp_clear.h
Normal file
43
src/gallium/drivers/llvmpipe/lp_clear.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#ifndef SP_CLEAR_H
|
||||
#define SP_CLEAR_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
struct pipe_context;
|
||||
|
||||
extern void
|
||||
llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
|
||||
double depth, unsigned stencil);
|
||||
|
||||
|
||||
#endif /* SP_CLEAR_H */
|
||||
317
src/gallium/drivers/llvmpipe/lp_context.c
Normal file
317
src/gallium/drivers/llvmpipe/lp_context.c
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
* Copyright 2008 VMware, Inc. 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 "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_clear.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_flush.h"
|
||||
#include "lp_prim_setup.h"
|
||||
#include "lp_prim_vbuf.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_winsys.h"
|
||||
#include "lp_query.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Map any drawing surfaces which aren't already mapped
|
||||
*/
|
||||
void
|
||||
llvmpipe_map_transfers(struct llvmpipe_context *lp)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
|
||||
lp_tile_cache_map_transfers(lp->cbuf_cache[i]);
|
||||
}
|
||||
|
||||
lp_tile_cache_map_transfers(lp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unmap any mapped drawing surfaces
|
||||
*/
|
||||
void
|
||||
llvmpipe_unmap_transfers(struct llvmpipe_context *lp)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < lp->framebuffer.nr_cbufs; i++)
|
||||
lp_flush_tile_cache(lp, lp->cbuf_cache[i]);
|
||||
lp_flush_tile_cache(lp, lp->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
|
||||
lp_tile_cache_unmap_transfers(lp->cbuf_cache[i]);
|
||||
}
|
||||
lp_tile_cache_unmap_transfers(lp->zsbuf_cache);
|
||||
}
|
||||
|
||||
|
||||
static void llvmpipe_destroy( struct pipe_context *pipe )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
|
||||
uint i;
|
||||
|
||||
if (llvmpipe->draw)
|
||||
draw_destroy( llvmpipe->draw );
|
||||
|
||||
for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
|
||||
llvmpipe->quad[i].polygon_stipple->destroy( llvmpipe->quad[i].polygon_stipple );
|
||||
llvmpipe->quad[i].earlyz->destroy( llvmpipe->quad[i].earlyz );
|
||||
llvmpipe->quad[i].shade->destroy( llvmpipe->quad[i].shade );
|
||||
llvmpipe->quad[i].alpha_test->destroy( llvmpipe->quad[i].alpha_test );
|
||||
llvmpipe->quad[i].depth_test->destroy( llvmpipe->quad[i].depth_test );
|
||||
llvmpipe->quad[i].stencil_test->destroy( llvmpipe->quad[i].stencil_test );
|
||||
llvmpipe->quad[i].occlusion->destroy( llvmpipe->quad[i].occlusion );
|
||||
llvmpipe->quad[i].coverage->destroy( llvmpipe->quad[i].coverage );
|
||||
llvmpipe->quad[i].blend->destroy( llvmpipe->quad[i].blend );
|
||||
llvmpipe->quad[i].colormask->destroy( llvmpipe->quad[i].colormask );
|
||||
llvmpipe->quad[i].output->destroy( llvmpipe->quad[i].output );
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]);
|
||||
lp_destroy_tile_cache(llvmpipe->zsbuf_cache);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
lp_destroy_tile_cache(llvmpipe->tex_cache[i]);
|
||||
|
||||
for (i = 0; i < Elements(llvmpipe->constants); i++) {
|
||||
if (llvmpipe->constants[i].buffer) {
|
||||
pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
FREE( llvmpipe );
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
llvmpipe_is_texture_referenced( struct pipe_context *pipe,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
|
||||
unsigned i;
|
||||
|
||||
if(llvmpipe->dirty_render_cache) {
|
||||
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
|
||||
if(llvmpipe->framebuffer.cbufs[i] &&
|
||||
llvmpipe->framebuffer.cbufs[i]->texture == texture)
|
||||
return PIPE_REFERENCED_FOR_WRITE;
|
||||
}
|
||||
if(llvmpipe->framebuffer.zsbuf &&
|
||||
llvmpipe->framebuffer.zsbuf->texture == texture)
|
||||
return PIPE_REFERENCED_FOR_WRITE;
|
||||
}
|
||||
|
||||
/* FIXME: we also need to do the same for the texture cache */
|
||||
|
||||
return PIPE_UNREFERENCED;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
llvmpipe_is_buffer_referenced( struct pipe_context *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
return PIPE_UNREFERENCED;
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
llvmpipe_create( struct pipe_screen *screen )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = CALLOC_STRUCT(llvmpipe_context);
|
||||
uint i;
|
||||
|
||||
util_init_math();
|
||||
|
||||
#ifdef PIPE_ARCH_X86
|
||||
llvmpipe->use_sse = !debug_get_bool_option( "GALLIUM_NOSSE", FALSE );
|
||||
#else
|
||||
llvmpipe->use_sse = FALSE;
|
||||
#endif
|
||||
|
||||
llvmpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
|
||||
|
||||
llvmpipe->pipe.winsys = screen->winsys;
|
||||
llvmpipe->pipe.screen = screen;
|
||||
llvmpipe->pipe.destroy = llvmpipe_destroy;
|
||||
|
||||
/* state setters */
|
||||
llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
|
||||
llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
|
||||
llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
|
||||
|
||||
llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
|
||||
llvmpipe->pipe.bind_sampler_states = llvmpipe_bind_sampler_states;
|
||||
llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
|
||||
|
||||
llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
|
||||
llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
|
||||
llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
|
||||
|
||||
llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
|
||||
llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
|
||||
llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
|
||||
|
||||
llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
|
||||
llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
|
||||
llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
|
||||
|
||||
llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
|
||||
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
|
||||
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
|
||||
|
||||
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
|
||||
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
|
||||
llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
|
||||
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
|
||||
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
|
||||
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
|
||||
llvmpipe->pipe.set_sampler_textures = llvmpipe_set_sampler_textures;
|
||||
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
|
||||
|
||||
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
|
||||
llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
|
||||
|
||||
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
|
||||
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
|
||||
llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
|
||||
llvmpipe->pipe.set_edgeflags = llvmpipe_set_edgeflags;
|
||||
|
||||
|
||||
llvmpipe->pipe.clear = llvmpipe_clear;
|
||||
llvmpipe->pipe.flush = llvmpipe_flush;
|
||||
|
||||
llvmpipe->pipe.is_texture_referenced = llvmpipe_is_texture_referenced;
|
||||
llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced;
|
||||
|
||||
llvmpipe_init_query_funcs( llvmpipe );
|
||||
llvmpipe_init_texture_funcs( llvmpipe );
|
||||
|
||||
/*
|
||||
* Alloc caches for accessing drawing surfaces and textures.
|
||||
* Must be before quad stage setup!
|
||||
*/
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
|
||||
llvmpipe->cbuf_cache[i] = lp_create_tile_cache( screen );
|
||||
llvmpipe->zsbuf_cache = lp_create_tile_cache( screen );
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
llvmpipe->tex_cache[i] = lp_create_tile_cache( screen );
|
||||
|
||||
|
||||
/* setup quad rendering stages */
|
||||
for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
|
||||
llvmpipe->quad[i].polygon_stipple = lp_quad_polygon_stipple_stage(llvmpipe);
|
||||
llvmpipe->quad[i].earlyz = lp_quad_earlyz_stage(llvmpipe);
|
||||
llvmpipe->quad[i].shade = lp_quad_shade_stage(llvmpipe);
|
||||
llvmpipe->quad[i].alpha_test = lp_quad_alpha_test_stage(llvmpipe);
|
||||
llvmpipe->quad[i].depth_test = lp_quad_depth_test_stage(llvmpipe);
|
||||
llvmpipe->quad[i].stencil_test = lp_quad_stencil_test_stage(llvmpipe);
|
||||
llvmpipe->quad[i].occlusion = lp_quad_occlusion_stage(llvmpipe);
|
||||
llvmpipe->quad[i].coverage = lp_quad_coverage_stage(llvmpipe);
|
||||
llvmpipe->quad[i].blend = lp_quad_blend_stage(llvmpipe);
|
||||
llvmpipe->quad[i].colormask = lp_quad_colormask_stage(llvmpipe);
|
||||
llvmpipe->quad[i].output = lp_quad_output_stage(llvmpipe);
|
||||
}
|
||||
|
||||
/* vertex shader samplers */
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples_vertex;
|
||||
llvmpipe->tgsi.vert_samplers[i].unit = i;
|
||||
llvmpipe->tgsi.vert_samplers[i].lp = llvmpipe;
|
||||
llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i];
|
||||
llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i];
|
||||
}
|
||||
|
||||
/* fragment shader samplers */
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples_fragment;
|
||||
llvmpipe->tgsi.frag_samplers[i].unit = i;
|
||||
llvmpipe->tgsi.frag_samplers[i].lp = llvmpipe;
|
||||
llvmpipe->tgsi.frag_samplers[i].cache = llvmpipe->tex_cache[i];
|
||||
llvmpipe->tgsi.frag_samplers_list[i] = &llvmpipe->tgsi.frag_samplers[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Create drawing context and plug our rendering stage into it.
|
||||
*/
|
||||
llvmpipe->draw = draw_create();
|
||||
if (!llvmpipe->draw)
|
||||
goto fail;
|
||||
|
||||
draw_texture_samplers(llvmpipe->draw,
|
||||
PIPE_MAX_SAMPLERS,
|
||||
(struct tgsi_sampler **)
|
||||
llvmpipe->tgsi.vert_samplers_list);
|
||||
|
||||
llvmpipe->setup = lp_draw_render_stage(llvmpipe);
|
||||
if (!llvmpipe->setup)
|
||||
goto fail;
|
||||
|
||||
if (debug_get_bool_option( "SP_NO_RAST", FALSE ))
|
||||
llvmpipe->no_rast = TRUE;
|
||||
|
||||
if (debug_get_bool_option( "SP_NO_VBUF", FALSE )) {
|
||||
/* Deprecated path -- vbuf is the intended interface to the draw module:
|
||||
*/
|
||||
draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->setup);
|
||||
}
|
||||
else {
|
||||
lp_init_vbuf(llvmpipe);
|
||||
}
|
||||
|
||||
/* plug in AA line/point stages */
|
||||
draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe);
|
||||
draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe);
|
||||
|
||||
#if USE_DRAW_STAGE_PSTIPPLE
|
||||
/* Do polygon stipple w/ texture map + frag prog? */
|
||||
draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
|
||||
#endif
|
||||
|
||||
lp_init_surface_functions(llvmpipe);
|
||||
|
||||
return &llvmpipe->pipe;
|
||||
|
||||
fail:
|
||||
llvmpipe_destroy(&llvmpipe->pipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
168
src/gallium/drivers/llvmpipe/lp_context.h
Normal file
168
src/gallium/drivers/llvmpipe/lp_context.h
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_CONTEXT_H
|
||||
#define SP_CONTEXT_H
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "draw/draw_vertex.h"
|
||||
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_tex_sample.h"
|
||||
|
||||
|
||||
/**
|
||||
* This is a temporary variable for testing draw-stage polygon stipple.
|
||||
* If zero, do stipple in lp_quad_stipple.c
|
||||
*/
|
||||
#define USE_DRAW_STAGE_PSTIPPLE 1
|
||||
|
||||
/* Number of threads working on individual quads.
|
||||
* Setting to 1 disables this feature.
|
||||
*/
|
||||
#define SP_NUM_QUAD_THREADS 1
|
||||
|
||||
struct llvmpipe_vbuf_render;
|
||||
struct draw_context;
|
||||
struct draw_stage;
|
||||
struct llvmpipe_tile_cache;
|
||||
struct lp_fragment_shader;
|
||||
struct lp_vertex_shader;
|
||||
|
||||
|
||||
struct llvmpipe_context {
|
||||
struct pipe_context pipe; /**< base class */
|
||||
|
||||
/** Constant state objects */
|
||||
const struct pipe_blend_state *blend;
|
||||
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
||||
const struct pipe_depth_stencil_alpha_state *depth_stencil;
|
||||
const struct pipe_rasterizer_state *rasterizer;
|
||||
const struct lp_fragment_shader *fs;
|
||||
const struct lp_vertex_shader *vs;
|
||||
|
||||
/** Other rendering state */
|
||||
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 pipe_texture *texture[PIPE_MAX_SAMPLERS];
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
|
||||
|
||||
unsigned num_samplers;
|
||||
unsigned num_textures;
|
||||
unsigned num_vertex_elements;
|
||||
unsigned num_vertex_buffers;
|
||||
|
||||
unsigned dirty; /**< Mask of SP_NEW_x flags */
|
||||
|
||||
/* Counter for occlusion queries. Note this supports overlapping
|
||||
* queries.
|
||||
*/
|
||||
uint64_t occlusion_count;
|
||||
unsigned active_query_count;
|
||||
|
||||
/** Mapped vertex buffers */
|
||||
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
|
||||
|
||||
/** Mapped constant buffers */
|
||||
void *mapped_constants[PIPE_SHADER_TYPES];
|
||||
|
||||
/** Vertex format */
|
||||
struct vertex_info vertex_info;
|
||||
struct vertex_info vertex_info_vbuf;
|
||||
|
||||
/** Which vertex shader output slot contains point size */
|
||||
int psize_slot;
|
||||
|
||||
unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */
|
||||
|
||||
/** Derived from scissor and surface bounds: */
|
||||
struct pipe_scissor_state cliprect;
|
||||
|
||||
unsigned line_stipple_counter;
|
||||
|
||||
/** Software quad rendering pipeline */
|
||||
struct {
|
||||
struct quad_stage *polygon_stipple;
|
||||
struct quad_stage *earlyz;
|
||||
struct quad_stage *shade;
|
||||
struct quad_stage *alpha_test;
|
||||
struct quad_stage *stencil_test;
|
||||
struct quad_stage *depth_test;
|
||||
struct quad_stage *occlusion;
|
||||
struct quad_stage *coverage;
|
||||
struct quad_stage *blend;
|
||||
struct quad_stage *colormask;
|
||||
struct quad_stage *output;
|
||||
|
||||
struct quad_stage *first; /**< points to one of the above stages */
|
||||
} quad[SP_NUM_QUAD_THREADS];
|
||||
|
||||
/** TGSI exec things */
|
||||
struct {
|
||||
struct lp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
|
||||
struct lp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
|
||||
struct lp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
|
||||
struct lp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
|
||||
} tgsi;
|
||||
|
||||
/** The primitive drawing context */
|
||||
struct draw_context *draw;
|
||||
struct draw_stage *setup;
|
||||
struct draw_stage *vbuf;
|
||||
struct llvmpipe_vbuf_render *vbuf_render;
|
||||
|
||||
boolean dirty_render_cache;
|
||||
|
||||
struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
|
||||
struct llvmpipe_tile_cache *zsbuf_cache;
|
||||
|
||||
struct llvmpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
|
||||
|
||||
unsigned use_sse : 1;
|
||||
unsigned dump_fs : 1;
|
||||
unsigned no_rast : 1;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct llvmpipe_context *
|
||||
llvmpipe_context( struct pipe_context *pipe )
|
||||
{
|
||||
return (struct llvmpipe_context *)pipe;
|
||||
}
|
||||
|
||||
#endif /* SP_CONTEXT_H */
|
||||
|
||||
194
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
Normal file
194
src/gallium/drivers/llvmpipe/lp_draw_arrays.c
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Author:
|
||||
* Brian Paul
|
||||
* Keith Whitwell
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_prim.h"
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_map_constant_buffers(struct llvmpipe_context *lp)
|
||||
{
|
||||
struct pipe_winsys *ws = lp->pipe.winsys;
|
||||
uint i, size;
|
||||
|
||||
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
|
||||
if (lp->constants[i].buffer && lp->constants[i].buffer->size)
|
||||
lp->mapped_constants[i] = ws->buffer_map(ws, lp->constants[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
}
|
||||
|
||||
if (lp->constants[PIPE_SHADER_VERTEX].buffer)
|
||||
size = lp->constants[PIPE_SHADER_VERTEX].buffer->size;
|
||||
else
|
||||
size = 0;
|
||||
|
||||
draw_set_mapped_constant_buffer(lp->draw,
|
||||
lp->mapped_constants[PIPE_SHADER_VERTEX],
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp)
|
||||
{
|
||||
struct pipe_winsys *ws = lp->pipe.winsys;
|
||||
uint i;
|
||||
|
||||
/* really need to flush all prims since the vert/frag shaders const buffers
|
||||
* are going away now.
|
||||
*/
|
||||
draw_flush(lp->draw);
|
||||
|
||||
draw_set_mapped_constant_buffer(lp->draw, NULL, 0);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (lp->constants[i].buffer && lp->constants[i].buffer->size)
|
||||
ws->buffer_unmap(ws, lp->constants[i].buffer);
|
||||
lp->mapped_constants[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
unsigned start, unsigned count)
|
||||
{
|
||||
return llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draw vertex arrays, with optional indexing.
|
||||
* Basically, map the vertex buffers (and drawing surfaces), then hand off
|
||||
* the drawing to the 'draw' module.
|
||||
*/
|
||||
boolean
|
||||
llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned mode, unsigned start, unsigned count)
|
||||
{
|
||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||
struct draw_context *draw = lp->draw;
|
||||
unsigned i;
|
||||
|
||||
lp->reduced_api_prim = u_reduced_prim(mode);
|
||||
|
||||
if (lp->dirty)
|
||||
llvmpipe_update_derived( lp );
|
||||
|
||||
llvmpipe_map_transfers(lp);
|
||||
llvmpipe_map_constant_buffers(lp);
|
||||
|
||||
/*
|
||||
* Map vertex buffers
|
||||
*/
|
||||
for (i = 0; i < lp->num_vertex_buffers; i++) {
|
||||
void *buf
|
||||
= pipe_buffer_map(pipe->screen,
|
||||
lp->vertex_buffer[i].buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_vertex_buffer(draw, i, buf);
|
||||
}
|
||||
|
||||
/* Map index buffer, if present */
|
||||
if (indexBuffer) {
|
||||
void *mapped_indexes
|
||||
= pipe_buffer_map(pipe->screen, indexBuffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ);
|
||||
draw_set_mapped_element_buffer_range(draw, indexSize,
|
||||
min_index,
|
||||
max_index,
|
||||
mapped_indexes);
|
||||
}
|
||||
else {
|
||||
/* no index/element buffer */
|
||||
draw_set_mapped_element_buffer_range(draw, 0, start,
|
||||
start + count - 1, NULL);
|
||||
}
|
||||
|
||||
/* draw! */
|
||||
draw_arrays(draw, mode, start, count);
|
||||
|
||||
/*
|
||||
* unmap vertex/index buffers - will cause draw module to flush
|
||||
*/
|
||||
for (i = 0; i < lp->num_vertex_buffers; i++) {
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
pipe_buffer_unmap(pipe->screen, lp->vertex_buffer[i].buffer);
|
||||
}
|
||||
if (indexBuffer) {
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
pipe_buffer_unmap(pipe->screen, indexBuffer);
|
||||
}
|
||||
|
||||
|
||||
/* Note: leave drawing surfaces mapped */
|
||||
llvmpipe_unmap_constant_buffers(lp);
|
||||
|
||||
lp->dirty_render_cache = TRUE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
llvmpipe_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned mode, unsigned start, unsigned count)
|
||||
{
|
||||
return llvmpipe_draw_range_elements( pipe, indexBuffer,
|
||||
indexSize,
|
||||
0, 0xffffffff,
|
||||
mode, start, count );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
|
||||
{
|
||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||
draw_set_edgeflags(lp->draw, edgeflags);
|
||||
}
|
||||
94
src/gallium/drivers/llvmpipe/lp_flush.c
Normal file
94
src/gallium/drivers/llvmpipe/lp_flush.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 "pipe/p_defines.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "lp_flush.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "lp_winsys.h"
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_flush( struct pipe_context *pipe,
|
||||
unsigned flags,
|
||||
struct pipe_fence_handle **fence )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
uint i;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
|
||||
for (i = 0; i < llvmpipe->num_textures; i++) {
|
||||
lp_flush_tile_cache(llvmpipe, llvmpipe->tex_cache[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & PIPE_FLUSH_RENDER_CACHE) {
|
||||
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++)
|
||||
if (llvmpipe->cbuf_cache[i])
|
||||
lp_flush_tile_cache(llvmpipe, llvmpipe->cbuf_cache[i]);
|
||||
|
||||
if (llvmpipe->zsbuf_cache)
|
||||
lp_flush_tile_cache(llvmpipe, llvmpipe->zsbuf_cache);
|
||||
|
||||
/* Need this call for hardware buffers before swapbuffers.
|
||||
*
|
||||
* there should probably be another/different flush-type function
|
||||
* that's called before swapbuffers because we don't always want
|
||||
* to unmap surfaces when flushing.
|
||||
*/
|
||||
llvmpipe_unmap_transfers(llvmpipe);
|
||||
|
||||
llvmpipe->dirty_render_cache = FALSE;
|
||||
}
|
||||
|
||||
/* Enable to dump BMPs of the color/depth buffers each frame */
|
||||
#if 0
|
||||
if(flags & PIPE_FLUSH_FRAME) {
|
||||
static unsigned frame_no = 1;
|
||||
static char filename[256];
|
||||
util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no);
|
||||
debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[0]);
|
||||
util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no);
|
||||
debug_dump_surface_bmp(filename, llvmpipe->framebuffer.zsbuf);
|
||||
++frame_no;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fence)
|
||||
*fence = NULL;
|
||||
}
|
||||
|
||||
37
src/gallium/drivers/llvmpipe/lp_flush.h
Normal file
37
src/gallium/drivers/llvmpipe/lp_flush.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SP_FLUSH_H
|
||||
#define SP_FLUSH_H
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_fence_handle;
|
||||
|
||||
void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
|
||||
struct pipe_fence_handle **fence);
|
||||
|
||||
#endif
|
||||
54
src/gallium/drivers/llvmpipe/lp_fs.h
Normal file
54
src/gallium/drivers/llvmpipe/lp_fs.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_FS_H
|
||||
#define SP_FS_H
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ);
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ);
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ);
|
||||
|
||||
struct tgsi_interp_coef;
|
||||
struct tgsi_exec_vector;
|
||||
|
||||
void lp_setup_pos_vector(const struct tgsi_interp_coef *coef,
|
||||
float x, float y,
|
||||
struct tgsi_exec_vector *quadpos);
|
||||
|
||||
|
||||
#endif
|
||||
162
src/gallium/drivers/llvmpipe/lp_fs_exec.c
Normal file
162
src/gallium/drivers/llvmpipe/lp_fs_exec.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Execute fragment shader using the TGSI interpreter.
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_fs.h"
|
||||
#include "lp_quad.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of lp_fragment_shader
|
||||
*/
|
||||
struct lp_exec_fragment_shader
|
||||
{
|
||||
struct lp_fragment_shader base;
|
||||
/* No other members for now */
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct lp_exec_fragment_shader *
|
||||
lp_exec_fragment_shader(const struct lp_fragment_shader *base)
|
||||
{
|
||||
return (struct lp_exec_fragment_shader *) base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute quad X,Y,Z,W for the four fragments in a quad.
|
||||
*
|
||||
* This should really be part of the compiled shader.
|
||||
*/
|
||||
void
|
||||
lp_setup_pos_vector(const struct tgsi_interp_coef *coef,
|
||||
float x, float y,
|
||||
struct tgsi_exec_vector *quadpos)
|
||||
{
|
||||
uint chan;
|
||||
/* do X */
|
||||
quadpos->xyzw[0].f[0] = x;
|
||||
quadpos->xyzw[0].f[1] = x + 1;
|
||||
quadpos->xyzw[0].f[2] = x;
|
||||
quadpos->xyzw[0].f[3] = x + 1;
|
||||
|
||||
/* do Y */
|
||||
quadpos->xyzw[1].f[0] = y;
|
||||
quadpos->xyzw[1].f[1] = y;
|
||||
quadpos->xyzw[1].f[2] = y + 1;
|
||||
quadpos->xyzw[1].f[3] = y + 1;
|
||||
|
||||
/* do Z and W for all fragments in the quad */
|
||||
for (chan = 2; chan < 4; chan++) {
|
||||
const float dadx = coef->dadx[chan];
|
||||
const float dady = coef->dady[chan];
|
||||
const float a0 = coef->a0[chan] + dadx * x + dady * y;
|
||||
quadpos->xyzw[chan].f[0] = a0;
|
||||
quadpos->xyzw[chan].f[1] = a0 + dadx;
|
||||
quadpos->xyzw[chan].f[2] = a0 + dady;
|
||||
quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
exec_prepare( const struct lp_fragment_shader *base,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler **samplers )
|
||||
{
|
||||
/*
|
||||
* Bind tokens/shader to the interpreter's machine state.
|
||||
* Avoid redundant binding.
|
||||
*/
|
||||
if (machine->Tokens != base->shader.tokens) {
|
||||
tgsi_exec_machine_bind_shader( machine,
|
||||
base->shader.tokens,
|
||||
PIPE_MAX_SAMPLERS,
|
||||
samplers );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TODO: hide the machine struct in here somewhere, remove from this
|
||||
* interface:
|
||||
*/
|
||||
static unsigned
|
||||
exec_run( const struct lp_fragment_shader *base,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct quad_header *quad )
|
||||
{
|
||||
/* Compute X, Y, Z, W vals for this quad */
|
||||
lp_setup_pos_vector(quad->posCoef,
|
||||
(float)quad->input.x0, (float)quad->input.y0,
|
||||
&machine->QuadPos);
|
||||
|
||||
return tgsi_exec_machine_run( machine );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
exec_delete( struct lp_fragment_shader *base )
|
||||
{
|
||||
FREE((void *) base->shader.tokens);
|
||||
FREE(base);
|
||||
}
|
||||
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_exec(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct lp_exec_fragment_shader *shader;
|
||||
|
||||
/* Decide whether we'll be codegenerating this shader and if so do
|
||||
* that now.
|
||||
*/
|
||||
|
||||
shader = CALLOC_STRUCT(lp_exec_fragment_shader);
|
||||
if (!shader)
|
||||
return NULL;
|
||||
|
||||
/* we need to keep a local copy of the tokens */
|
||||
shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
|
||||
shader->base.prepare = exec_prepare;
|
||||
shader->base.run = exec_run;
|
||||
shader->base.delete = exec_delete;
|
||||
|
||||
return &shader->base;
|
||||
}
|
||||
205
src/gallium/drivers/llvmpipe/lp_fs_llvm.c
Normal file
205
src/gallium/drivers/llvmpipe/lp_fs_llvm.c
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Execute fragment shader using LLVM code generation.
|
||||
* Authors:
|
||||
* Zack Rusin
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_fs.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_sse2.h"
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
* Subclass of lp_fragment_shader
|
||||
*/
|
||||
struct lp_llvm_fragment_shader
|
||||
{
|
||||
struct lp_fragment_shader base;
|
||||
struct gallivm_prog *llvm_prog;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
shade_quad_llvm(struct quad_stage *qs,
|
||||
struct quad_header *quad)
|
||||
{
|
||||
struct quad_shade_stage *qss = quad_shade_stage(qs);
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
float dests[4][16][4] ALIGN16_ATTRIB;
|
||||
float inputs[4][16][4] ALIGN16_ATTRIB;
|
||||
const float fx = (float) quad->x0;
|
||||
const float fy = (float) quad->y0;
|
||||
struct gallivm_prog *llvm = qss->llvm_prog;
|
||||
|
||||
inputs[0][0][0] = fx;
|
||||
inputs[1][0][0] = fx + 1.0f;
|
||||
inputs[2][0][0] = fx;
|
||||
inputs[3][0][0] = fx + 1.0f;
|
||||
|
||||
inputs[0][0][1] = fy;
|
||||
inputs[1][0][1] = fy;
|
||||
inputs[2][0][1] = fy + 1.0f;
|
||||
inputs[3][0][1] = fy + 1.0f;
|
||||
|
||||
|
||||
gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef);
|
||||
|
||||
#if DLLVM
|
||||
debug_printf("MASK = %d\n", quad->mask);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j,
|
||||
inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
quad->mask &=
|
||||
gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs,
|
||||
llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT],
|
||||
qss->samplers);
|
||||
#if DLLVM
|
||||
debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n",
|
||||
dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3],
|
||||
dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]);
|
||||
#endif
|
||||
|
||||
/* store result color */
|
||||
if (qss->colorOutSlot >= 0) {
|
||||
unsigned i;
|
||||
/* XXX need to handle multiple color outputs someday */
|
||||
allvmrt(qss->stage.llvmpipe->fs->info.output_semantic_name[qss->colorOutSlot]
|
||||
== TGSI_SEMANTIC_COLOR);
|
||||
for (i = 0; i < QUAD_SIZE; ++i) {
|
||||
quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0];
|
||||
quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1];
|
||||
quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2];
|
||||
quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3];
|
||||
}
|
||||
}
|
||||
#if DLLVM
|
||||
for (int i = 0; i < QUAD_SIZE; ++i) {
|
||||
debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot,
|
||||
quad->outputs.color[0][0][i],
|
||||
quad->outputs.color[0][1][i],
|
||||
quad->outputs.color[0][2][i],
|
||||
quad->outputs.color[0][3][i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* store result Z */
|
||||
if (qss->depthOutSlot >= 0) {
|
||||
/* output[slot] is new Z */
|
||||
uint i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
quad->outputs.depth[i] = dests[i][0][2];
|
||||
}
|
||||
}
|
||||
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] = inputs[i][0][2];
|
||||
}
|
||||
}
|
||||
#if DLLVM
|
||||
debug_printf("D [%f, %f, %f, %f] mask = %d\n",
|
||||
quad->outputs.depth[0],
|
||||
quad->outputs.depth[1],
|
||||
quad->outputs.depth[2],
|
||||
quad->outputs.depth[3], quad->mask);
|
||||
#endif
|
||||
|
||||
/* shader may cull fragments */
|
||||
if( quad->mask ) {
|
||||
qs->next->run( qs->next, quad );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
run_llvm_fs( const struct lp_fragment_shader *base,
|
||||
struct foo *machine )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
delete_llvm_fs( struct lp_fragment_shader *base )
|
||||
{
|
||||
FREE(base);
|
||||
}
|
||||
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct lp_llvm_fragment_shader *shader = NULL;
|
||||
|
||||
/* LLVM fragment shaders currently disabled:
|
||||
*/
|
||||
state = CALLOC_STRUCT(lp_llvm_shader_state);
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
state->llvm_prog = 0;
|
||||
|
||||
if (!gallivm_global_cpu_engine()) {
|
||||
gallivm_cpu_engine_create(state->llvm_prog);
|
||||
}
|
||||
else
|
||||
gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog);
|
||||
|
||||
if (shader) {
|
||||
shader->base.run = run_llvm_fs;
|
||||
shader->base.delete = delete_llvm_fs;
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_llvm(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
169
src/gallium/drivers/llvmpipe/lp_fs_sse.c
Normal file
169
src/gallium/drivers/llvmpipe/lp_fs_sse.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Execute fragment shader using runtime SSE code generation.
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_fs.h"
|
||||
#include "lp_quad.h"
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
#include "tgsi/tgsi_sse2.h"
|
||||
|
||||
|
||||
#if defined(PIPE_ARCH_X86)
|
||||
|
||||
#include "rtasm/rtasm_x86sse.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of lp_fragment_shader
|
||||
*/
|
||||
struct lp_sse_fragment_shader
|
||||
{
|
||||
struct lp_fragment_shader base;
|
||||
struct x86_function sse2_program;
|
||||
tgsi_sse2_fs_function func;
|
||||
float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct lp_sse_fragment_shader *
|
||||
lp_sse_fragment_shader(const struct lp_fragment_shader *base)
|
||||
{
|
||||
return (struct lp_sse_fragment_shader *) base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fs_sse_prepare( const struct lp_fragment_shader *base,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct tgsi_sampler **samplers )
|
||||
{
|
||||
machine->Samplers = samplers;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: codegenerate the whole run function, skip this wrapper.
|
||||
* TODO: break dependency on tgsi_exec_machine struct
|
||||
* TODO: push Position calculation into the generated shader
|
||||
* TODO: process >1 quad at a time
|
||||
*/
|
||||
static unsigned
|
||||
fs_sse_run( const struct lp_fragment_shader *base,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct quad_header *quad )
|
||||
{
|
||||
struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base);
|
||||
|
||||
/* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */
|
||||
lp_setup_pos_vector(quad->posCoef,
|
||||
(float)quad->input.x0, (float)quad->input.y0,
|
||||
machine->Temps);
|
||||
|
||||
/* init kill mask */
|
||||
tgsi_set_kill_mask(machine, 0x0);
|
||||
tgsi_set_exec_mask(machine, 1, 1, 1, 1);
|
||||
|
||||
shader->func( machine,
|
||||
machine->Consts,
|
||||
(const float (*)[4])shader->immediates,
|
||||
machine->InterpCoefs
|
||||
// , &machine->QuadPos
|
||||
);
|
||||
|
||||
return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fs_sse_delete( struct lp_fragment_shader *base )
|
||||
{
|
||||
struct lp_sse_fragment_shader *shader = lp_sse_fragment_shader(base);
|
||||
|
||||
x86_release_func( &shader->sse2_program );
|
||||
FREE(shader);
|
||||
}
|
||||
|
||||
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct lp_sse_fragment_shader *shader;
|
||||
|
||||
if (!llvmpipe->use_sse)
|
||||
return NULL;
|
||||
|
||||
shader = CALLOC_STRUCT(lp_sse_fragment_shader);
|
||||
if (!shader)
|
||||
return NULL;
|
||||
|
||||
x86_init_func( &shader->sse2_program );
|
||||
|
||||
if (!tgsi_emit_sse2( templ->tokens, &shader->sse2_program,
|
||||
shader->immediates, FALSE )) {
|
||||
FREE(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program );
|
||||
if (!shader->func) {
|
||||
x86_release_func( &shader->sse2_program );
|
||||
FREE(shader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shader->base.shader.tokens = NULL; /* don't hold reference to templ->tokens */
|
||||
shader->base.prepare = fs_sse_prepare;
|
||||
shader->base.run = fs_sse_run;
|
||||
shader->base.delete = fs_sse_delete;
|
||||
|
||||
return &shader->base;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
/* Maybe put this variant in the header file.
|
||||
*/
|
||||
struct lp_fragment_shader *
|
||||
llvmpipe_create_fs_sse(struct llvmpipe_context *llvmpipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
190
src/gallium/drivers/llvmpipe/lp_prim_setup.c
Normal file
190
src/gallium/drivers/llvmpipe/lp_prim_setup.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \brief A draw stage that drives our triangle setup routines from
|
||||
* within the draw pipeline. One of two ways to drive setup, the
|
||||
* other being in lp_prim_vbuf.c.
|
||||
*
|
||||
* \author Keith Whitwell <keith@tungstengraphics.com>
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_setup.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_prim_setup.h"
|
||||
#include "draw/draw_pipe.h"
|
||||
#include "draw/draw_vertex.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
/**
|
||||
* Triangle setup info (derived from draw_stage).
|
||||
* Also used for line drawing (taking some liberties).
|
||||
*/
|
||||
struct setup_stage {
|
||||
struct draw_stage stage; /**< This must be first (base class) */
|
||||
|
||||
struct setup_context *setup;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Basically a cast wrapper.
|
||||
*/
|
||||
static INLINE struct setup_stage *setup_stage( struct draw_stage *stage )
|
||||
{
|
||||
return (struct setup_stage *)stage;
|
||||
}
|
||||
|
||||
|
||||
typedef const float (*cptrf4)[4];
|
||||
|
||||
static void
|
||||
do_tri(struct draw_stage *stage, struct prim_header *prim)
|
||||
{
|
||||
struct setup_stage *setup = setup_stage( stage );
|
||||
|
||||
setup_tri( setup->setup,
|
||||
(cptrf4)prim->v[0]->data,
|
||||
(cptrf4)prim->v[1]->data,
|
||||
(cptrf4)prim->v[2]->data );
|
||||
}
|
||||
|
||||
static void
|
||||
do_line(struct draw_stage *stage, struct prim_header *prim)
|
||||
{
|
||||
struct setup_stage *setup = setup_stage( stage );
|
||||
|
||||
setup_line( setup->setup,
|
||||
(cptrf4)prim->v[0]->data,
|
||||
(cptrf4)prim->v[1]->data );
|
||||
}
|
||||
|
||||
static void
|
||||
do_point(struct draw_stage *stage, struct prim_header *prim)
|
||||
{
|
||||
struct setup_stage *setup = setup_stage( stage );
|
||||
|
||||
setup_point( setup->setup,
|
||||
(cptrf4)prim->v[0]->data );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void setup_begin( struct draw_stage *stage )
|
||||
{
|
||||
struct setup_stage *setup = setup_stage(stage);
|
||||
|
||||
setup_prepare( setup->setup );
|
||||
|
||||
stage->point = do_point;
|
||||
stage->line = do_line;
|
||||
stage->tri = do_tri;
|
||||
}
|
||||
|
||||
|
||||
static void setup_first_point( struct draw_stage *stage,
|
||||
struct prim_header *header )
|
||||
{
|
||||
setup_begin(stage);
|
||||
stage->point( stage, header );
|
||||
}
|
||||
|
||||
static void setup_first_line( struct draw_stage *stage,
|
||||
struct prim_header *header )
|
||||
{
|
||||
setup_begin(stage);
|
||||
stage->line( stage, header );
|
||||
}
|
||||
|
||||
|
||||
static void setup_first_tri( struct draw_stage *stage,
|
||||
struct prim_header *header )
|
||||
{
|
||||
setup_begin(stage);
|
||||
stage->tri( stage, header );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void setup_flush( struct draw_stage *stage,
|
||||
unsigned flags )
|
||||
{
|
||||
stage->point = setup_first_point;
|
||||
stage->line = setup_first_line;
|
||||
stage->tri = setup_first_tri;
|
||||
}
|
||||
|
||||
|
||||
static void reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void render_destroy( struct draw_stage *stage )
|
||||
{
|
||||
struct setup_stage *ssetup = setup_stage(stage);
|
||||
setup_destroy_context(ssetup->setup);
|
||||
FREE( stage );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new primitive setup/render stage.
|
||||
*/
|
||||
struct draw_stage *lp_draw_render_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct setup_stage *sstage = CALLOC_STRUCT(setup_stage);
|
||||
|
||||
sstage->setup = setup_create_context(llvmpipe);
|
||||
sstage->stage.draw = llvmpipe->draw;
|
||||
sstage->stage.point = setup_first_point;
|
||||
sstage->stage.line = setup_first_line;
|
||||
sstage->stage.tri = setup_first_tri;
|
||||
sstage->stage.flush = setup_flush;
|
||||
sstage->stage.reset_stipple_counter = reset_stipple_counter;
|
||||
sstage->stage.destroy = render_destroy;
|
||||
|
||||
return (struct draw_stage *)sstage;
|
||||
}
|
||||
|
||||
struct setup_context *
|
||||
lp_draw_setup_context( struct draw_stage *stage )
|
||||
{
|
||||
struct setup_stage *ssetup = setup_stage(stage);
|
||||
return ssetup->setup;
|
||||
}
|
||||
|
||||
void
|
||||
lp_draw_flush( struct draw_stage *stage )
|
||||
{
|
||||
stage->flush( stage, 0 );
|
||||
}
|
||||
85
src/gallium/drivers/llvmpipe/lp_prim_setup.h
Normal file
85
src/gallium/drivers/llvmpipe/lp_prim_setup.h
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef SP_PRIM_SETUP_H
|
||||
#define SP_PRIM_SETUP_H
|
||||
|
||||
|
||||
/**
|
||||
* vbuf is a special stage to gather the stream of triangles, lines, points
|
||||
* together and reconstruct vertex buffers for hardware upload.
|
||||
*
|
||||
* First attempt, work in progress.
|
||||
*
|
||||
* TODO:
|
||||
* - separate out vertex buffer building and primitive emit, ie >1 draw per vb.
|
||||
* - tell vbuf stage how to build hw vertices directly
|
||||
* - pass vbuf stage a buffer pointer for direct emit to agp/vram.
|
||||
*
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
struct draw_stage;
|
||||
struct llvmpipe_context;
|
||||
|
||||
|
||||
typedef void (*vbuf_draw_func)( struct pipe_context *pipe,
|
||||
unsigned prim,
|
||||
const ushort *elements,
|
||||
unsigned nr_elements,
|
||||
const void *vertex_buffer,
|
||||
unsigned nr_vertices );
|
||||
|
||||
|
||||
extern struct draw_stage *
|
||||
lp_draw_render_stage( struct llvmpipe_context *llvmpipe );
|
||||
|
||||
extern struct setup_context *
|
||||
lp_draw_setup_context( struct draw_stage * );
|
||||
|
||||
extern void
|
||||
lp_draw_flush( struct draw_stage * );
|
||||
|
||||
|
||||
extern struct draw_stage *
|
||||
lp_draw_vbuf_stage( struct draw_context *draw_context,
|
||||
struct pipe_context *pipe,
|
||||
vbuf_draw_func draw );
|
||||
|
||||
|
||||
#endif /* SP_PRIM_SETUP_H */
|
||||
585
src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
Normal file
585
src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
Normal file
|
|
@ -0,0 +1,585 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Interface between 'draw' module's output and the llvmpipe rasterizer/setup
|
||||
* code. When the 'draw' module has finished filling a vertex buffer, the
|
||||
* draw_arrays() functions below will be called. Loop over the vertices and
|
||||
* call the point/line/tri setup functions.
|
||||
*
|
||||
* Authors
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_prim_vbuf.h"
|
||||
#include "lp_prim_setup.h"
|
||||
#include "lp_setup.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vbuf.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
#define SP_MAX_VBUF_INDEXES 1024
|
||||
#define SP_MAX_VBUF_SIZE 4096
|
||||
|
||||
typedef const float (*cptrf4)[4];
|
||||
|
||||
/**
|
||||
* Subclass of vbuf_render.
|
||||
*/
|
||||
struct llvmpipe_vbuf_render
|
||||
{
|
||||
struct vbuf_render base;
|
||||
struct llvmpipe_context *llvmpipe;
|
||||
uint prim;
|
||||
uint vertex_size;
|
||||
uint nr_vertices;
|
||||
uint vertex_buffer_size;
|
||||
void *vertex_buffer;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static struct llvmpipe_vbuf_render *
|
||||
llvmpipe_vbuf_render(struct vbuf_render *vbr)
|
||||
{
|
||||
return (struct llvmpipe_vbuf_render *) vbr;
|
||||
}
|
||||
|
||||
|
||||
static const struct vertex_info *
|
||||
lp_vbuf_get_vertex_info(struct vbuf_render *vbr)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe);
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
lp_vbuf_allocate_vertices(struct vbuf_render *vbr,
|
||||
ushort vertex_size, ushort nr_vertices)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
unsigned size = vertex_size * nr_vertices;
|
||||
|
||||
if (cvbr->vertex_buffer_size < size) {
|
||||
align_free(cvbr->vertex_buffer);
|
||||
cvbr->vertex_buffer = align_malloc(size, 16);
|
||||
cvbr->vertex_buffer_size = size;
|
||||
}
|
||||
|
||||
cvbr->vertex_size = vertex_size;
|
||||
cvbr->nr_vertices = nr_vertices;
|
||||
|
||||
return cvbr->vertex_buffer != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
lp_vbuf_release_vertices(struct vbuf_render *vbr)
|
||||
{
|
||||
#if 0
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
const struct vertex_info *info =
|
||||
llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe);
|
||||
const float *vtx = (const float *) cvbr->vertex_buffer;
|
||||
uint i, j;
|
||||
debug_printf("%s (vtx_size = %u, vtx_used = %u)\n",
|
||||
__FUNCTION__, cvbr->vertex_size, cvbr->nr_vertices);
|
||||
for (i = 0; i < cvbr->nr_vertices; i++) {
|
||||
for (j = 0; j < info->num_attribs; j++) {
|
||||
uint k;
|
||||
switch (info->attrib[j].emit) {
|
||||
case EMIT_4F: k = 4; break;
|
||||
case EMIT_3F: k = 3; break;
|
||||
case EMIT_2F: k = 2; break;
|
||||
case EMIT_1F: k = 1; break;
|
||||
default: assert(0);
|
||||
}
|
||||
debug_printf("Vert %u attr %u: ", i, j);
|
||||
while (k-- > 0) {
|
||||
debug_printf("%g ", vtx[0]);
|
||||
vtx++;
|
||||
}
|
||||
debug_printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* keep the old allocation for next time */
|
||||
}
|
||||
|
||||
static void *
|
||||
lp_vbuf_map_vertices(struct vbuf_render *vbr)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
return cvbr->vertex_buffer;
|
||||
}
|
||||
|
||||
static void
|
||||
lp_vbuf_unmap_vertices(struct vbuf_render *vbr,
|
||||
ushort min_index,
|
||||
ushort max_index )
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
|
||||
/* XXX: break this dependency - make setup_context live under
|
||||
* llvmpipe, rename the old "setup" draw stage to something else.
|
||||
*/
|
||||
struct setup_context *setup_ctx = lp_draw_setup_context(cvbr->llvmpipe->setup);
|
||||
|
||||
setup_prepare( setup_ctx );
|
||||
|
||||
cvbr->prim = prim;
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static INLINE cptrf4 get_vert( const void *vertex_buffer,
|
||||
int index,
|
||||
int stride )
|
||||
{
|
||||
return (cptrf4)((char *)vertex_buffer + index * stride);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* draw elements / indexed primitives
|
||||
*/
|
||||
static void
|
||||
lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
|
||||
const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float);
|
||||
const void *vertex_buffer = cvbr->vertex_buffer;
|
||||
unsigned i;
|
||||
|
||||
/* XXX: break this dependency - make setup_context live under
|
||||
* llvmpipe, rename the old "setup" draw stage to something else.
|
||||
*/
|
||||
struct draw_stage *setup = llvmpipe->setup;
|
||||
struct setup_context *setup_ctx = lp_draw_setup_context(setup);
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < nr; i++) {
|
||||
setup_point( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 1; i < nr; i += 2) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
if (nr) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[nr-1], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-(i&1)], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride));
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-2], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[i-3], stride),
|
||||
get_vert(vertex_buffer, indices[i-0], stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* Almost same as tri fan but the _first_ vertex specifies the flat
|
||||
* shading color. Note that the first polygon vertex is passed as
|
||||
* the last triangle vertex here.
|
||||
* flatshade_first state makes no difference.
|
||||
*/
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, indices[i-0], stride),
|
||||
get_vert(vertex_buffer, indices[i-1], stride),
|
||||
get_vert(vertex_buffer, indices[0], stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* XXX: why are we calling this??? If we had to call something, it
|
||||
* would be a function in lp_setup.c:
|
||||
*/
|
||||
lp_draw_flush( setup );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is hit when the draw module is working in pass-through mode.
|
||||
* It's up to us to convert the vertex array into point/line/tri prims.
|
||||
*/
|
||||
static void
|
||||
lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
|
||||
const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float);
|
||||
const void *vertex_buffer =
|
||||
(void *) get_vert(cvbr->vertex_buffer, start, stride);
|
||||
unsigned i;
|
||||
|
||||
/* XXX: break this dependency - make setup_context live under
|
||||
* llvmpipe, rename the old "setup" draw stage to something else.
|
||||
*/
|
||||
struct draw_stage *setup = llvmpipe->setup;
|
||||
struct setup_context *setup_ctx = lp_draw_setup_context(setup);
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < nr; i++) {
|
||||
setup_point( setup_ctx,
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINES:
|
||||
for (i = 1; i < nr; i += 2) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
for (i = 1; i < nr; i ++) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
if (nr) {
|
||||
setup_line( setup_ctx,
|
||||
get_vert(vertex_buffer, nr-1, stride),
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
for (i = 2; i < nr; i += 3) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
for (i = 2; i < nr; i++) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i+(i&1)-1, stride),
|
||||
get_vert(vertex_buffer, i-(i&1), stride),
|
||||
get_vert(vertex_buffer, i-2, stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i+(i&1)-2, stride),
|
||||
get_vert(vertex_buffer, i-(i&1)-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, 0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, 0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
for (i = 3; i < nr; i += 4) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-3, stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
for (i = 3; i < nr; i += 2) {
|
||||
if (llvmpipe->rasterizer->flatshade_first) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, i-3, stride) );
|
||||
}
|
||||
else {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-2, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-3, stride),
|
||||
get_vert(vertex_buffer, i-0, stride) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* Almost same as tri fan but the _first_ vertex specifies the flat
|
||||
* shading color. Note that the first polygon vertex is passed as
|
||||
* the last triangle vertex here.
|
||||
* flatshade_first state makes no difference.
|
||||
*/
|
||||
for (i = 2; i < nr; i += 1) {
|
||||
setup_tri( setup_ctx,
|
||||
get_vert(vertex_buffer, i-1, stride),
|
||||
get_vert(vertex_buffer, i-0, stride),
|
||||
get_vert(vertex_buffer, 0, stride) );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
lp_vbuf_destroy(struct vbuf_render *vbr)
|
||||
{
|
||||
struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
|
||||
cvbr->llvmpipe->vbuf_render = NULL;
|
||||
FREE(cvbr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the post-transform vertex buffer information for the given
|
||||
* context.
|
||||
*/
|
||||
void
|
||||
lp_init_vbuf(struct llvmpipe_context *lp)
|
||||
{
|
||||
assert(lp->draw);
|
||||
|
||||
lp->vbuf_render = CALLOC_STRUCT(llvmpipe_vbuf_render);
|
||||
|
||||
lp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES;
|
||||
lp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
|
||||
|
||||
lp->vbuf_render->base.get_vertex_info = lp_vbuf_get_vertex_info;
|
||||
lp->vbuf_render->base.allocate_vertices = lp_vbuf_allocate_vertices;
|
||||
lp->vbuf_render->base.map_vertices = lp_vbuf_map_vertices;
|
||||
lp->vbuf_render->base.unmap_vertices = lp_vbuf_unmap_vertices;
|
||||
lp->vbuf_render->base.set_primitive = lp_vbuf_set_primitive;
|
||||
lp->vbuf_render->base.draw = lp_vbuf_draw;
|
||||
lp->vbuf_render->base.draw_arrays = lp_vbuf_draw_arrays;
|
||||
lp->vbuf_render->base.release_vertices = lp_vbuf_release_vertices;
|
||||
lp->vbuf_render->base.destroy = lp_vbuf_destroy;
|
||||
|
||||
lp->vbuf_render->llvmpipe = lp;
|
||||
|
||||
lp->vbuf = draw_vbuf_stage(lp->draw, &lp->vbuf_render->base);
|
||||
|
||||
draw_set_rasterize_stage(lp->draw, lp->vbuf);
|
||||
|
||||
draw_set_render(lp->draw, &lp->vbuf_render->base);
|
||||
}
|
||||
38
src/gallium/drivers/llvmpipe/lp_prim_vbuf.h
Normal file
38
src/gallium/drivers/llvmpipe/lp_prim_vbuf.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SP_VBUF_H
|
||||
#define SP_VBUF_H
|
||||
|
||||
|
||||
struct llvmpipe_context;
|
||||
|
||||
extern void
|
||||
lp_init_vbuf(struct llvmpipe_context *llvmpipe);
|
||||
|
||||
|
||||
#endif /* SP_VBUF_H */
|
||||
106
src/gallium/drivers/llvmpipe/lp_quad.h
Normal file
106
src/gallium/drivers/llvmpipe/lp_quad.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_QUAD_H
|
||||
#define SP_QUAD_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
|
||||
|
||||
#define QUAD_PRIM_POINT 1
|
||||
#define QUAD_PRIM_LINE 2
|
||||
#define QUAD_PRIM_TRI 3
|
||||
|
||||
|
||||
/* The rasterizer generates 2x2 quads of fragment and feeds them to
|
||||
* the current fp_machine (see below).
|
||||
* Remember that Y=0=top with Y increasing down the window.
|
||||
*/
|
||||
#define QUAD_TOP_LEFT 0
|
||||
#define QUAD_TOP_RIGHT 1
|
||||
#define QUAD_BOTTOM_LEFT 2
|
||||
#define QUAD_BOTTOM_RIGHT 3
|
||||
|
||||
#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT)
|
||||
#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT)
|
||||
#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT)
|
||||
#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT)
|
||||
#define MASK_ALL 0xf
|
||||
|
||||
|
||||
/**
|
||||
* Quad stage inputs (pos, coverage, front/back face, etc)
|
||||
*/
|
||||
struct quad_header_input
|
||||
{
|
||||
int x0, y0; /**< quad window pos, always even */
|
||||
float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */
|
||||
unsigned facing:1; /**< Front (0) or back (1) facing? */
|
||||
unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Quad stage inputs/outputs.
|
||||
*/
|
||||
struct quad_header_inout
|
||||
{
|
||||
unsigned mask:4;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Quad stage outputs (color & depth).
|
||||
*/
|
||||
struct quad_header_output
|
||||
{
|
||||
/** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
|
||||
float color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
|
||||
float depth[QUAD_SIZE];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes everything we need to know about a 2x2 pixel block. Uses
|
||||
* "Channel-Serial" or "SoA" layout.
|
||||
*/
|
||||
struct quad_header {
|
||||
struct quad_header_input input;
|
||||
struct quad_header_inout inout;
|
||||
struct quad_header_output output;
|
||||
|
||||
const struct tgsi_interp_coef *coef;
|
||||
const struct tgsi_interp_coef *posCoef;
|
||||
|
||||
unsigned nr_attrs;
|
||||
};
|
||||
|
||||
#endif /* SP_QUAD_H */
|
||||
108
src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c
Normal file
108
src/gallium/drivers/llvmpipe/lp_quad_alpha_test.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
|
||||
/**
|
||||
* quad alpha test
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
static void
|
||||
alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
const float ref = llvmpipe->depth_stencil->alpha.ref_value;
|
||||
unsigned passMask = 0x0, j;
|
||||
const uint cbuf = 0; /* only output[0].alpha is tested */
|
||||
const float *aaaa = quad->output.color[cbuf][3];
|
||||
|
||||
switch (llvmpipe->depth_stencil->alpha.func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
break;
|
||||
case PIPE_FUNC_LESS:
|
||||
/*
|
||||
* If mask were an array [4] we could do this SIMD-style:
|
||||
* passMask = (quad->outputs.color[0][3] <= vec4(ref));
|
||||
*/
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] < ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] == ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] <= ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GREATER:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] > ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] != ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (aaaa[j] >= ref) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
passMask = MASK_ALL;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
quad->inout.mask &= passMask;
|
||||
|
||||
if (quad->inout.mask)
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void alpha_test_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void alpha_test_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *
|
||||
lp_quad_alpha_test_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = alpha_test_begin;
|
||||
stage->run = alpha_test_quad;
|
||||
stage->destroy = alpha_test_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
777
src/gallium/drivers/llvmpipe/lp_quad_blend.c
Normal file
777
src/gallium/drivers/llvmpipe/lp_quad_blend.c
Normal file
|
|
@ -0,0 +1,777 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* quad blending
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
|
||||
|
||||
#define VEC4_COPY(DST, SRC) \
|
||||
do { \
|
||||
DST[0] = SRC[0]; \
|
||||
DST[1] = SRC[1]; \
|
||||
DST[2] = SRC[2]; \
|
||||
DST[3] = SRC[3]; \
|
||||
} while(0)
|
||||
|
||||
#define VEC4_SCALAR(DST, SRC) \
|
||||
do { \
|
||||
DST[0] = SRC; \
|
||||
DST[1] = SRC; \
|
||||
DST[2] = SRC; \
|
||||
DST[3] = SRC; \
|
||||
} while(0)
|
||||
|
||||
#define VEC4_ADD(R, A, B) \
|
||||
do { \
|
||||
R[0] = A[0] + B[0]; \
|
||||
R[1] = A[1] + B[1]; \
|
||||
R[2] = A[2] + B[2]; \
|
||||
R[3] = A[3] + B[3]; \
|
||||
} while (0)
|
||||
|
||||
#define VEC4_SUB(R, A, B) \
|
||||
do { \
|
||||
R[0] = A[0] - B[0]; \
|
||||
R[1] = A[1] - B[1]; \
|
||||
R[2] = A[2] - B[2]; \
|
||||
R[3] = A[3] - B[3]; \
|
||||
} while (0)
|
||||
|
||||
/** Add and limit result to ceiling of 1.0 */
|
||||
#define VEC4_ADD_SAT(R, A, B) \
|
||||
do { \
|
||||
R[0] = A[0] + B[0]; if (R[0] > 1.0f) R[0] = 1.0f; \
|
||||
R[1] = A[1] + B[1]; if (R[1] > 1.0f) R[1] = 1.0f; \
|
||||
R[2] = A[2] + B[2]; if (R[2] > 1.0f) R[2] = 1.0f; \
|
||||
R[3] = A[3] + B[3]; if (R[3] > 1.0f) R[3] = 1.0f; \
|
||||
} while (0)
|
||||
|
||||
/** Subtract and limit result to floor of 0.0 */
|
||||
#define VEC4_SUB_SAT(R, A, B) \
|
||||
do { \
|
||||
R[0] = A[0] - B[0]; if (R[0] < 0.0f) R[0] = 0.0f; \
|
||||
R[1] = A[1] - B[1]; if (R[1] < 0.0f) R[1] = 0.0f; \
|
||||
R[2] = A[2] - B[2]; if (R[2] < 0.0f) R[2] = 0.0f; \
|
||||
R[3] = A[3] - B[3]; if (R[3] < 0.0f) R[3] = 0.0f; \
|
||||
} while (0)
|
||||
|
||||
#define VEC4_MUL(R, A, B) \
|
||||
do { \
|
||||
R[0] = A[0] * B[0]; \
|
||||
R[1] = A[1] * B[1]; \
|
||||
R[2] = A[2] * B[2]; \
|
||||
R[3] = A[3] * B[3]; \
|
||||
} while (0)
|
||||
|
||||
#define VEC4_MIN(R, A, B) \
|
||||
do { \
|
||||
R[0] = (A[0] < B[0]) ? A[0] : B[0]; \
|
||||
R[1] = (A[1] < B[1]) ? A[1] : B[1]; \
|
||||
R[2] = (A[2] < B[2]) ? A[2] : B[2]; \
|
||||
R[3] = (A[3] < B[3]) ? A[3] : B[3]; \
|
||||
} while (0)
|
||||
|
||||
#define VEC4_MAX(R, A, B) \
|
||||
do { \
|
||||
R[0] = (A[0] > B[0]) ? A[0] : B[0]; \
|
||||
R[1] = (A[1] > B[1]) ? A[1] : B[1]; \
|
||||
R[2] = (A[2] > B[2]) ? A[2] : B[2]; \
|
||||
R[3] = (A[3] > B[3]) ? A[3] : B[3]; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
static void
|
||||
logicop_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
uint cbuf;
|
||||
|
||||
/* loop over colorbuffer outputs */
|
||||
for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) {
|
||||
float dest[4][QUAD_SIZE];
|
||||
ubyte src[4][4], dst[4][4], res[4][4];
|
||||
uint *src4 = (uint *) src;
|
||||
uint *dst4 = (uint *) dst;
|
||||
uint *res4 = (uint *) res;
|
||||
struct llvmpipe_cached_tile *
|
||||
tile = lp_get_cached_tile(llvmpipe,
|
||||
llvmpipe->cbuf_cache[cbuf],
|
||||
quad->input.x0, quad->input.y0);
|
||||
float (*quadColor)[4] = quad->output.color[cbuf];
|
||||
uint i, j;
|
||||
|
||||
/* get/swizzle dest colors */
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
|
||||
int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
|
||||
for (i = 0; i < 4; i++) {
|
||||
dest[i][j] = tile->data.color[y][x][i];
|
||||
}
|
||||
}
|
||||
|
||||
/* convert to ubyte */
|
||||
for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
|
||||
dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
|
||||
dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
|
||||
dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
|
||||
dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
|
||||
|
||||
src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
|
||||
src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
|
||||
src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
|
||||
src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
|
||||
}
|
||||
|
||||
switch (llvmpipe->blend->logicop_func) {
|
||||
case PIPE_LOGICOP_CLEAR:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = 0;
|
||||
break;
|
||||
case PIPE_LOGICOP_NOR:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~(src4[j] | dst4[j]);
|
||||
break;
|
||||
case PIPE_LOGICOP_AND_INVERTED:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~src4[j] & dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_COPY_INVERTED:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~src4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_AND_REVERSE:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = src4[j] & ~dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_XOR:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = dst4[j] ^ src4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_NAND:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~(src4[j] & dst4[j]);
|
||||
break;
|
||||
case PIPE_LOGICOP_AND:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = src4[j] & dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_EQUIV:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~(src4[j] ^ dst4[j]);
|
||||
break;
|
||||
case PIPE_LOGICOP_NOOP:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_OR_INVERTED:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~src4[j] | dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_COPY:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = src4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_OR_REVERSE:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = src4[j] | ~dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_OR:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = src4[j] | dst4[j];
|
||||
break;
|
||||
case PIPE_LOGICOP_SET:
|
||||
for (j = 0; j < 4; j++)
|
||||
res4[j] = ~0;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
quadColor[j][0] = ubyte_to_float(res[j][0]);
|
||||
quadColor[j][1] = ubyte_to_float(res[j][1]);
|
||||
quadColor[j][2] = ubyte_to_float(res[j][2]);
|
||||
quadColor[j][3] = ubyte_to_float(res[j][3]);
|
||||
}
|
||||
}
|
||||
|
||||
/* pass quad to next stage */
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
blend_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
static const float zero[4] = { 0, 0, 0, 0 };
|
||||
static const float one[4] = { 1, 1, 1, 1 };
|
||||
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
uint cbuf;
|
||||
|
||||
if (llvmpipe->blend->logicop_enable) {
|
||||
logicop_quad(qs, quad);
|
||||
return;
|
||||
}
|
||||
|
||||
/* loop over colorbuffer outputs */
|
||||
for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) {
|
||||
float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
|
||||
struct llvmpipe_cached_tile *tile
|
||||
= lp_get_cached_tile(llvmpipe,
|
||||
llvmpipe->cbuf_cache[cbuf],
|
||||
quad->input.x0, quad->input.y0);
|
||||
float (*quadColor)[4] = quad->output.color[cbuf];
|
||||
uint i, j;
|
||||
|
||||
/* get/swizzle dest colors */
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
|
||||
int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
|
||||
for (i = 0; i < 4; i++) {
|
||||
dest[i][j] = tile->data.color[y][x][i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute src/first term RGB
|
||||
*/
|
||||
switch (llvmpipe->blend->rgb_src_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
VEC4_COPY(source[0], quadColor[0]); /* R */
|
||||
VEC4_COPY(source[1], quadColor[1]); /* G */
|
||||
VEC4_COPY(source[2], quadColor[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
{
|
||||
const float *alpha = quadColor[3];
|
||||
VEC4_MUL(source[0], quadColor[0], alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
{
|
||||
const float *alpha = dest[3];
|
||||
VEC4_MUL(source[0], quadColor[0], alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
{
|
||||
const float *alpha = quadColor[3];
|
||||
float diff[4], temp[4];
|
||||
VEC4_SUB(diff, one, dest[3]);
|
||||
VEC4_MIN(temp, alpha, diff);
|
||||
VEC4_MUL(source[0], quadColor[0], temp); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], temp); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], temp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
{
|
||||
float comp[4];
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[0]); /* R */
|
||||
VEC4_MUL(source[0], quadColor[0], comp); /* R */
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[1]); /* G */
|
||||
VEC4_MUL(source[1], quadColor[1], comp); /* G */
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[2]); /* B */
|
||||
VEC4_MUL(source[2], quadColor[2], comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
{
|
||||
float alpha[4];
|
||||
VEC4_SCALAR(alpha, llvmpipe->blend_color.color[3]);
|
||||
VEC4_MUL(source[0], quadColor[0], alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC1_COLOR:
|
||||
assert(0); /* to do */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC1_ALPHA:
|
||||
assert(0); /* to do */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
VEC4_COPY(source[0], zero); /* R */
|
||||
VEC4_COPY(source[1], zero); /* G */
|
||||
VEC4_COPY(source[2], zero); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
|
||||
VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
|
||||
VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
|
||||
VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
|
||||
VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
|
||||
VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
{
|
||||
float inv_alpha[4];
|
||||
VEC4_SUB(inv_alpha, one, quadColor[3]);
|
||||
VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
{
|
||||
float inv_alpha[4];
|
||||
VEC4_SUB(inv_alpha, one, dest[3]);
|
||||
VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, dest[0]); /* R */
|
||||
VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
|
||||
VEC4_SUB(inv_comp, one, dest[1]); /* G */
|
||||
VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
|
||||
VEC4_SUB(inv_comp, one, dest[2]); /* B */
|
||||
VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
/* R */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[0]);
|
||||
VEC4_MUL(source[0], quadColor[0], inv_comp);
|
||||
/* G */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[1]);
|
||||
VEC4_MUL(source[1], quadColor[1], inv_comp);
|
||||
/* B */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[2]);
|
||||
VEC4_MUL(source[2], quadColor[2], inv_comp);
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
{
|
||||
float inv_alpha[4];
|
||||
VEC4_SCALAR(inv_alpha, 1.0f - llvmpipe->blend_color.color[3]);
|
||||
VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
|
||||
VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
|
||||
VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
|
||||
assert(0); /* to do */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
|
||||
assert(0); /* to do */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute src/first term A
|
||||
*/
|
||||
switch (llvmpipe->blend->alpha_src_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
VEC4_COPY(source[3], quadColor[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
{
|
||||
const float *alpha = quadColor[3];
|
||||
VEC4_MUL(source[3], quadColor[3], alpha); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
/* multiply alpha by 1.0 */
|
||||
VEC4_COPY(source[3], quadColor[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
{
|
||||
float comp[4];
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */
|
||||
VEC4_MUL(source[3], quadColor[3], comp); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
VEC4_COPY(source[3], zero); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
{
|
||||
float inv_alpha[4];
|
||||
VEC4_SUB(inv_alpha, one, quadColor[3]);
|
||||
VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
{
|
||||
float inv_alpha[4];
|
||||
VEC4_SUB(inv_alpha, one, dest[3]);
|
||||
VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
{
|
||||
float inv_comp[4];
|
||||
/* A */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]);
|
||||
VEC4_MUL(source[3], quadColor[3], inv_comp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute dest/second term RGB
|
||||
*/
|
||||
switch (llvmpipe->blend->rgb_dst_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
/* dest = dest * 1 NO-OP, leave dest as-is */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
|
||||
VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
|
||||
VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
|
||||
VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
|
||||
VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
|
||||
VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
|
||||
VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
|
||||
VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
|
||||
VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
assert(0); /* illegal */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
{
|
||||
float comp[4];
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[0]); /* R */
|
||||
VEC4_MUL(dest[0], dest[0], comp); /* R */
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[1]); /* G */
|
||||
VEC4_MUL(dest[1], dest[1], comp); /* G */
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[2]); /* B */
|
||||
VEC4_MUL(dest[2], dest[2], comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
{
|
||||
float comp[4];
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */
|
||||
VEC4_MUL(dest[0], dest[0], comp); /* R */
|
||||
VEC4_MUL(dest[1], dest[1], comp); /* G */
|
||||
VEC4_MUL(dest[2], dest[2], comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
VEC4_COPY(dest[0], zero); /* R */
|
||||
VEC4_COPY(dest[1], zero); /* G */
|
||||
VEC4_COPY(dest[2], zero); /* B */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC1_COLOR:
|
||||
case PIPE_BLENDFACTOR_SRC1_ALPHA:
|
||||
/* XXX what are these? */
|
||||
assert(0);
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
|
||||
VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
|
||||
VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
|
||||
VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
|
||||
VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
|
||||
VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
{
|
||||
float one_minus_alpha[QUAD_SIZE];
|
||||
VEC4_SUB(one_minus_alpha, one, quadColor[3]);
|
||||
VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
|
||||
VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
|
||||
VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, dest[3]); /* A */
|
||||
VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
|
||||
VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
|
||||
VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, dest[0]); /* R */
|
||||
VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
|
||||
VEC4_SUB(inv_comp, one, dest[1]); /* G */
|
||||
VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
|
||||
VEC4_SUB(inv_comp, one, dest[2]); /* B */
|
||||
VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
{
|
||||
float inv_comp[4];
|
||||
/* R */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[0]);
|
||||
VEC4_MUL(dest[0], dest[0], inv_comp);
|
||||
/* G */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[1]);
|
||||
VEC4_MUL(dest[1], dest[1], inv_comp);
|
||||
/* B */
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[2]);
|
||||
VEC4_MUL(dest[2], dest[2], inv_comp);
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]);
|
||||
VEC4_MUL(dest[0], dest[0], inv_comp);
|
||||
VEC4_MUL(dest[1], dest[1], inv_comp);
|
||||
VEC4_MUL(dest[2], dest[2], inv_comp);
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
|
||||
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
|
||||
/* XXX what are these? */
|
||||
assert(0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute dest/second term A
|
||||
*/
|
||||
switch (llvmpipe->blend->alpha_dst_factor) {
|
||||
case PIPE_BLENDFACTOR_ONE:
|
||||
/* dest = dest * 1 NO-OP, leave dest as-is */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA:
|
||||
VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_DST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_DST_ALPHA:
|
||||
VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
|
||||
assert(0); /* illegal */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_CONST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_CONST_ALPHA:
|
||||
{
|
||||
float comp[4];
|
||||
VEC4_SCALAR(comp, llvmpipe->blend_color.color[3]); /* A */
|
||||
VEC4_MUL(dest[3], dest[3], comp); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_ZERO:
|
||||
VEC4_COPY(dest[3], zero); /* A */
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_SRC_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
|
||||
{
|
||||
float one_minus_alpha[QUAD_SIZE];
|
||||
VEC4_SUB(one_minus_alpha, one, quadColor[3]);
|
||||
VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_DST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_DST_ALPHA:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SUB(inv_comp, one, dest[3]); /* A */
|
||||
VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
|
||||
}
|
||||
break;
|
||||
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
|
||||
/* fall-through */
|
||||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
|
||||
{
|
||||
float inv_comp[4];
|
||||
VEC4_SCALAR(inv_comp, 1.0f - llvmpipe->blend_color.color[3]);
|
||||
VEC4_MUL(dest[3], dest[3], inv_comp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Combine RGB terms
|
||||
*/
|
||||
switch (llvmpipe->blend->rgb_func) {
|
||||
case PIPE_BLEND_ADD:
|
||||
VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
|
||||
VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
|
||||
VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLEND_SUBTRACT:
|
||||
VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
|
||||
VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
|
||||
VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLEND_REVERSE_SUBTRACT:
|
||||
VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
|
||||
VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
|
||||
VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLEND_MIN:
|
||||
VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
|
||||
VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
|
||||
VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
|
||||
break;
|
||||
case PIPE_BLEND_MAX:
|
||||
VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
|
||||
VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
|
||||
VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Combine A terms
|
||||
*/
|
||||
switch (llvmpipe->blend->alpha_func) {
|
||||
case PIPE_BLEND_ADD:
|
||||
VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLEND_SUBTRACT:
|
||||
VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLEND_REVERSE_SUBTRACT:
|
||||
VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLEND_MIN:
|
||||
VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
|
||||
break;
|
||||
case PIPE_BLEND_MAX:
|
||||
VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
} /* cbuf loop */
|
||||
|
||||
/* pass blended quad to next stage */
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void blend_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void blend_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_blend_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = blend_begin;
|
||||
stage->run = blend_quad;
|
||||
stage->destroy = blend_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
74
src/gallium/drivers/llvmpipe/lp_quad_bufloop.c
Normal file
74
src/gallium/drivers/llvmpipe/lp_quad_bufloop.c
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
|
||||
|
||||
/**
|
||||
* Loop over colorbuffers, passing quad to next stage each time.
|
||||
*/
|
||||
static void
|
||||
cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE];
|
||||
unsigned i;
|
||||
|
||||
assert(sizeof(quad->outputs.color) == sizeof(tmp));
|
||||
assert(llvmpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
|
||||
|
||||
/* make copy of original colors since they can get modified
|
||||
* by blending and masking.
|
||||
* XXX we won't have to do this if the fragment program actually emits
|
||||
* N separate colors and we're drawing to N color buffers (MRT).
|
||||
* But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is
|
||||
* in effect, we need to save/restore colors like this.
|
||||
*/
|
||||
memcpy(tmp, quad->outputs.color, sizeof(tmp));
|
||||
|
||||
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
|
||||
/* set current cbuffer */
|
||||
#if 0 /* obsolete & going away */
|
||||
llvmpipe->current_cbuf = i;
|
||||
#endif
|
||||
|
||||
/* pass blended quad to next stage */
|
||||
qs->next->run(qs->next, quad);
|
||||
|
||||
/* restore quad's colors for next buffer */
|
||||
memcpy(quad->outputs.color, tmp, sizeof(tmp));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void cbuf_loop_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void cbuf_loop_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the colorbuffer loop stage.
|
||||
* This is used to implement multiple render targets and GL_FRONT_AND_BACK
|
||||
* rendering.
|
||||
*/
|
||||
struct quad_stage *lp_quad_bufloop_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = cbuf_loop_begin;
|
||||
stage->run = cbuf_loop_quad;
|
||||
stage->destroy = cbuf_loop_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
||||
116
src/gallium/drivers/llvmpipe/lp_quad_colormask.c
Normal file
116
src/gallium/drivers/llvmpipe/lp_quad_colormask.c
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \brief quad colormask stage
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* XXX colormask could be rolled into blending...
|
||||
*/
|
||||
static void
|
||||
colormask_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
uint cbuf;
|
||||
|
||||
/* loop over colorbuffer outputs */
|
||||
for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) {
|
||||
float dest[4][QUAD_SIZE];
|
||||
struct llvmpipe_cached_tile *tile
|
||||
= lp_get_cached_tile(llvmpipe,
|
||||
llvmpipe->cbuf_cache[cbuf],
|
||||
quad->input.x0, quad->input.y0);
|
||||
float (*quadColor)[4] = quad->output.color[cbuf];
|
||||
uint i, j;
|
||||
|
||||
/* get/swizzle dest colors */
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
|
||||
int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
|
||||
for (i = 0; i < 4; i++) {
|
||||
dest[i][j] = tile->data.color[y][x][i];
|
||||
}
|
||||
}
|
||||
|
||||
/* R */
|
||||
if (!(llvmpipe->blend->colormask & PIPE_MASK_R))
|
||||
COPY_4V(quadColor[0], dest[0]);
|
||||
|
||||
/* G */
|
||||
if (!(llvmpipe->blend->colormask & PIPE_MASK_G))
|
||||
COPY_4V(quadColor[1], dest[1]);
|
||||
|
||||
/* B */
|
||||
if (!(llvmpipe->blend->colormask & PIPE_MASK_B))
|
||||
COPY_4V(quadColor[2], dest[2]);
|
||||
|
||||
/* A */
|
||||
if (!(llvmpipe->blend->colormask & PIPE_MASK_A))
|
||||
COPY_4V(quadColor[3], dest[3]);
|
||||
}
|
||||
|
||||
/* pass quad to next stage */
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void colormask_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void colormask_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_colormask_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = colormask_begin;
|
||||
stage->run = colormask_quad;
|
||||
stage->destroy = colormask_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
94
src/gallium/drivers/llvmpipe/lp_quad_coverage.c
Normal file
94
src/gallium/drivers/llvmpipe/lp_quad_coverage.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Apply AA coverage to quad alpha valus
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
|
||||
|
||||
/**
|
||||
* Multiply quad's alpha values by the fragment coverage.
|
||||
*/
|
||||
static void
|
||||
coverage_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
const uint prim = quad->input.prim;
|
||||
|
||||
if ((llvmpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) ||
|
||||
(llvmpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) ||
|
||||
(llvmpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) {
|
||||
uint cbuf;
|
||||
|
||||
/* loop over colorbuffer outputs */
|
||||
for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) {
|
||||
float (*quadColor)[4] = quad->output.color[cbuf];
|
||||
unsigned j;
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
assert(quad->input.coverage[j] >= 0.0);
|
||||
assert(quad->input.coverage[j] <= 1.0);
|
||||
quadColor[3][j] *= quad->input.coverage[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void coverage_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void coverage_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_coverage_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = coverage_begin;
|
||||
stage->run = coverage_quad;
|
||||
stage->destroy = coverage_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
290
src/gallium/drivers/llvmpipe/lp_quad_depth_test.c
Normal file
290
src/gallium/drivers/llvmpipe/lp_quad_depth_test.c
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \brief Quad depth testing
|
||||
*/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
|
||||
/**
|
||||
* Do depth testing for a quad.
|
||||
* Not static since it's used by the stencil code.
|
||||
*/
|
||||
|
||||
/*
|
||||
* To increase efficiency, we should probably have multiple versions
|
||||
* of this function that are specifically for Z16, Z32 and FP Z buffers.
|
||||
* Try to effectively do that with codegen...
|
||||
*/
|
||||
|
||||
void
|
||||
lp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf;
|
||||
const enum pipe_format format = ps->format;
|
||||
unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
|
||||
unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
|
||||
unsigned zmask = 0;
|
||||
unsigned j;
|
||||
struct llvmpipe_cached_tile *tile
|
||||
= lp_get_cached_tile(llvmpipe, llvmpipe->zsbuf_cache, quad->input.x0, quad->input.y0);
|
||||
|
||||
assert(ps); /* shouldn't get here if there's no zbuffer */
|
||||
|
||||
/*
|
||||
* Convert quad's float depth values to int depth values (qzzzz).
|
||||
* If the Z buffer stores integer values, we _have_ to do the depth
|
||||
* compares with integers (not floats). Otherwise, the float->int->float
|
||||
* conversion of Z values (which isn't an identity function) will cause
|
||||
* Z-fighting errors.
|
||||
*
|
||||
* Also, get the zbuffer values (bzzzz) from the cached tile.
|
||||
*/
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
{
|
||||
float scale = 65535.0;
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
|
||||
}
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
bzzzz[j] = tile->data.depth16[y][x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
{
|
||||
double scale = (double) (uint) ~0UL;
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
|
||||
}
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
bzzzz[j] = tile->data.depth32[y][x];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
/* fall-through */
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
{
|
||||
float scale = (float) ((1 << 24) - 1);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
|
||||
}
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
/* fall-through */
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
{
|
||||
float scale = (float) ((1 << 24) - 1);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
|
||||
}
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
bzzzz[j] = tile->data.depth32[y][x] >> 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
switch (llvmpipe->depth_stencil->depth.func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
/* zmask = 0 */
|
||||
break;
|
||||
case PIPE_FUNC_LESS:
|
||||
/* Note this is pretty much a single sse or cell instruction.
|
||||
* Like this: quad->mask &= (quad->outputs.depth < zzzz);
|
||||
*/
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] < bzzzz[j])
|
||||
zmask |= 1 << j;
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] == bzzzz[j])
|
||||
zmask |= 1 << j;
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] <= bzzzz[j])
|
||||
zmask |= (1 << j);
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GREATER:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] > bzzzz[j])
|
||||
zmask |= (1 << j);
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] != bzzzz[j])
|
||||
zmask |= (1 << j);
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (qzzzz[j] >= bzzzz[j])
|
||||
zmask |= (1 << j);
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
zmask = MASK_ALL;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
quad->inout.mask &= zmask;
|
||||
|
||||
if (llvmpipe->depth_stencil->depth.writemask) {
|
||||
|
||||
/* This is also efficient with sse / spe instructions:
|
||||
*/
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (quad->inout.mask & (1 << j)) {
|
||||
bzzzz[j] = qzzzz[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* put updated Z values back into cached tile */
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
tile->data.depth16[y][x] = (ushort) bzzzz[j];
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_X8Z24_UNORM:
|
||||
/* fall-through */
|
||||
/* (yes, this falls through to a different case than above) */
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
tile->data.depth32[y][x] = bzzzz[j];
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
uint s8z24 = tile->data.depth32[y][x];
|
||||
s8z24 = (s8z24 & 0xff000000) | bzzzz[j];
|
||||
tile->data.depth32[y][x] = s8z24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
uint z24s8 = tile->data.depth32[y][x];
|
||||
z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8);
|
||||
tile->data.depth32[y][x] = z24s8;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
tile->data.depth32[y][x] = bzzzz[j] << 8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
lp_depth_test_quad(qs, quad);
|
||||
|
||||
if (quad->inout.mask)
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void depth_test_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void depth_test_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_depth_test_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = depth_test_begin;
|
||||
stage->run = depth_test_quad;
|
||||
stage->destroy = depth_test_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
88
src/gallium/drivers/llvmpipe/lp_quad_earlyz.c
Normal file
88
src/gallium/drivers/llvmpipe/lp_quad_earlyz.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* \brief Quad early-z testing
|
||||
*/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
|
||||
|
||||
/**
|
||||
* All this stage does is compute the quad's Z values (which is normally
|
||||
* done by the shading stage).
|
||||
* The next stage will do the actual depth test.
|
||||
*/
|
||||
static void
|
||||
earlyz_quad(
|
||||
struct quad_stage *qs,
|
||||
struct quad_header *quad )
|
||||
{
|
||||
const float fx = (float) quad->input.x0;
|
||||
const float fy = (float) quad->input.y0;
|
||||
const float dzdx = quad->posCoef->dadx[2];
|
||||
const float dzdy = quad->posCoef->dady[2];
|
||||
const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
|
||||
|
||||
quad->output.depth[0] = z0;
|
||||
quad->output.depth[1] = z0 + dzdx;
|
||||
quad->output.depth[2] = z0 + dzdy;
|
||||
quad->output.depth[3] = z0 + dzdx + dzdy;
|
||||
|
||||
qs->next->run( qs->next, quad );
|
||||
}
|
||||
|
||||
static void
|
||||
earlyz_begin(
|
||||
struct quad_stage *qs )
|
||||
{
|
||||
qs->next->begin( qs->next );
|
||||
}
|
||||
|
||||
static void
|
||||
earlyz_destroy(
|
||||
struct quad_stage *qs )
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
struct quad_stage *
|
||||
lp_quad_earlyz_stage(
|
||||
struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT( quad_stage );
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = earlyz_begin;
|
||||
stage->run = earlyz_quad;
|
||||
stage->destroy = earlyz_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
192
src/gallium/drivers/llvmpipe/lp_quad_fs.c
Normal file
192
src/gallium/drivers/llvmpipe/lp_quad_fs.c
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
* Copyright 2008 VMware, Inc. 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 "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_tex_sample.h"
|
||||
|
||||
|
||||
struct quad_shade_stage
|
||||
{
|
||||
struct quad_stage stage; /**< base class */
|
||||
struct tgsi_exec_machine *machine;
|
||||
struct tgsi_exec_vector *inputs, *outputs;
|
||||
};
|
||||
|
||||
|
||||
/** 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 llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
struct tgsi_exec_machine *machine = qss->machine;
|
||||
boolean z_written;
|
||||
|
||||
/* Consts do not require 16 byte alignment. */
|
||||
machine->Consts = llvmpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
|
||||
|
||||
machine->InterpCoefs = quad->coef;
|
||||
|
||||
/* run shader */
|
||||
quad->inout.mask &= llvmpipe->fs->run( llvmpipe->fs, machine, quad );
|
||||
|
||||
/* store outputs */
|
||||
z_written = FALSE;
|
||||
{
|
||||
const ubyte *sem_name = llvmpipe->fs->info.output_semantic_name;
|
||||
const ubyte *sem_index = llvmpipe->fs->info.output_semantic_index;
|
||||
const uint n = qss->stage.llvmpipe->fs->info.num_outputs;
|
||||
uint i;
|
||||
for (i = 0; i < n; i++) {
|
||||
switch (sem_name[i]) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
{
|
||||
uint cbuf = sem_index[i];
|
||||
memcpy(quad->output.color[cbuf],
|
||||
&machine->Outputs[i].xyzw[0].f[0],
|
||||
sizeof(quad->output.color[0]) );
|
||||
}
|
||||
break;
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
{
|
||||
uint j;
|
||||
for (j = 0; j < 4; j++) {
|
||||
quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j];
|
||||
}
|
||||
z_written = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!z_written) {
|
||||
/* compute Z values now, as in the quad earlyz stage */
|
||||
/* XXX we should really only do this if the earlyz stage is not used */
|
||||
const float fx = (float) quad->input.x0;
|
||||
const float fy = (float) quad->input.y0;
|
||||
const float dzdx = quad->posCoef->dadx[2];
|
||||
const float dzdy = quad->posCoef->dady[2];
|
||||
const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
|
||||
|
||||
quad->output.depth[0] = z0;
|
||||
quad->output.depth[1] = z0 + dzdx;
|
||||
quad->output.depth[2] = z0 + dzdy;
|
||||
quad->output.depth[3] = z0 + dzdx + dzdy;
|
||||
}
|
||||
|
||||
/* shader may cull fragments */
|
||||
if (quad->inout.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 llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
|
||||
llvmpipe->fs->prepare( llvmpipe->fs,
|
||||
qss->machine,
|
||||
(struct tgsi_sampler **)
|
||||
llvmpipe->tgsi.frag_samplers_list );
|
||||
|
||||
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_destroy(qss->machine);
|
||||
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *
|
||||
lp_quad_shade_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
|
||||
if (!qss)
|
||||
goto fail;
|
||||
|
||||
qss->stage.llvmpipe = llvmpipe;
|
||||
qss->stage.begin = shade_begin;
|
||||
qss->stage.run = shade_quad;
|
||||
qss->stage.destroy = shade_destroy;
|
||||
|
||||
qss->machine = tgsi_exec_machine_create();
|
||||
if (!qss->machine)
|
||||
goto fail;
|
||||
|
||||
return &qss->stage;
|
||||
|
||||
fail:
|
||||
if (qss && qss->machine)
|
||||
tgsi_exec_machine_destroy(qss->machine);
|
||||
|
||||
FREE(qss);
|
||||
return NULL;
|
||||
}
|
||||
85
src/gallium/drivers/llvmpipe/lp_quad_occlusion.c
Normal file
85
src/gallium/drivers/llvmpipe/lp_quad_occlusion.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Quad occlusion counter stage
|
||||
* \author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
|
||||
static unsigned count_bits( unsigned val )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; val ; val >>= 1)
|
||||
i += (val & 1);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
|
||||
llvmpipe->occlusion_count += count_bits(quad->inout.mask);
|
||||
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void occlusion_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void occlusion_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_occlusion_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = occlusion_begin;
|
||||
stage->run = occlusion_count_quad;
|
||||
stage->destroy = occlusion_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
103
src/gallium/drivers/llvmpipe/lp_quad_output.c
Normal file
103
src/gallium/drivers/llvmpipe/lp_quad_output.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
|
||||
/**
|
||||
* Last step of quad processing: write quad colors to the framebuffer,
|
||||
* taking mask into account.
|
||||
*/
|
||||
static void
|
||||
output_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
/* in-tile pos: */
|
||||
const int itx = quad->input.x0 % TILE_SIZE;
|
||||
const int ity = quad->input.y0 % TILE_SIZE;
|
||||
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
uint cbuf;
|
||||
|
||||
/* loop over colorbuffer outputs */
|
||||
for (cbuf = 0; cbuf < llvmpipe->framebuffer.nr_cbufs; cbuf++) {
|
||||
struct llvmpipe_cached_tile *tile
|
||||
= lp_get_cached_tile(llvmpipe,
|
||||
llvmpipe->cbuf_cache[cbuf],
|
||||
quad->input.x0, quad->input.y0);
|
||||
float (*quadColor)[4] = quad->output.color[cbuf];
|
||||
int i, j;
|
||||
|
||||
/* get/swizzle dest colors */
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (quad->inout.mask & (1 << j)) {
|
||||
int x = itx + (j & 1);
|
||||
int y = ity + (j >> 1);
|
||||
for (i = 0; i < 4; i++) { /* loop over color chans */
|
||||
tile->data.color[y][x][i] = quadColor[i][j];
|
||||
}
|
||||
if (0) {
|
||||
debug_printf("lp write pixel %d,%d: %g, %g, %g\n",
|
||||
quad->input.x0 + x,
|
||||
quad->input.y0 + y,
|
||||
quadColor[0][j],
|
||||
quadColor[1][j],
|
||||
quadColor[2][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void output_begin(struct quad_stage *qs)
|
||||
{
|
||||
assert(qs->next == NULL);
|
||||
}
|
||||
|
||||
|
||||
static void output_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_output_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = output_begin;
|
||||
stage->run = output_quad;
|
||||
stage->destroy = output_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
118
src/gallium/drivers/llvmpipe/lp_quad_pipe.c
Normal file
118
src/gallium/drivers/llvmpipe/lp_quad_pipe.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
static void
|
||||
lp_push_quad_first(
|
||||
struct llvmpipe_context *lp,
|
||||
struct quad_stage *quad,
|
||||
uint i )
|
||||
{
|
||||
quad->next = lp->quad[i].first;
|
||||
lp->quad[i].first = quad;
|
||||
}
|
||||
|
||||
static void
|
||||
lp_build_depth_stencil(
|
||||
struct llvmpipe_context *lp,
|
||||
uint i )
|
||||
{
|
||||
if (lp->depth_stencil->stencil[0].enabled ||
|
||||
lp->depth_stencil->stencil[1].enabled) {
|
||||
lp_push_quad_first( lp, lp->quad[i].stencil_test, i );
|
||||
}
|
||||
else if (lp->depth_stencil->depth.enabled &&
|
||||
lp->framebuffer.zsbuf) {
|
||||
lp_push_quad_first( lp, lp->quad[i].depth_test, i );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
lp_build_quad_pipeline(struct llvmpipe_context *lp)
|
||||
{
|
||||
uint i;
|
||||
|
||||
boolean early_depth_test =
|
||||
lp->depth_stencil->depth.enabled &&
|
||||
lp->framebuffer.zsbuf &&
|
||||
!lp->depth_stencil->alpha.enabled &&
|
||||
!lp->fs->info.uses_kill &&
|
||||
!lp->fs->info.writes_z;
|
||||
|
||||
/* build up the pipeline in reverse order... */
|
||||
for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
|
||||
lp->quad[i].first = lp->quad[i].output;
|
||||
|
||||
if (lp->blend->colormask != 0xf) {
|
||||
lp_push_quad_first( lp, lp->quad[i].colormask, i );
|
||||
}
|
||||
|
||||
if (lp->blend->blend_enable ||
|
||||
lp->blend->logicop_enable) {
|
||||
lp_push_quad_first( lp, lp->quad[i].blend, i );
|
||||
}
|
||||
|
||||
if (lp->active_query_count) {
|
||||
lp_push_quad_first( lp, lp->quad[i].occlusion, i );
|
||||
}
|
||||
|
||||
if (lp->rasterizer->poly_smooth ||
|
||||
lp->rasterizer->line_smooth ||
|
||||
lp->rasterizer->point_smooth) {
|
||||
lp_push_quad_first( lp, lp->quad[i].coverage, i );
|
||||
}
|
||||
|
||||
if (!early_depth_test) {
|
||||
lp_build_depth_stencil( lp, i );
|
||||
}
|
||||
|
||||
if (lp->depth_stencil->alpha.enabled) {
|
||||
lp_push_quad_first( lp, lp->quad[i].alpha_test, i );
|
||||
}
|
||||
|
||||
/* XXX always enable shader? */
|
||||
if (1) {
|
||||
lp_push_quad_first( lp, lp->quad[i].shade, i );
|
||||
}
|
||||
|
||||
if (early_depth_test) {
|
||||
lp_build_depth_stencil( lp, i );
|
||||
lp_push_quad_first( lp, lp->quad[i].earlyz, i );
|
||||
}
|
||||
|
||||
#if !USE_DRAW_STAGE_PSTIPPLE
|
||||
if (lp->rasterizer->poly_stipple_enable) {
|
||||
lp_push_quad_first( lp, lp->quad[i].polygon_stipple, i );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
74
src/gallium/drivers/llvmpipe/lp_quad_pipe.h
Normal file
74
src/gallium/drivers/llvmpipe/lp_quad_pipe.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_QUAD_PIPE_H
|
||||
#define SP_QUAD_PIPE_H
|
||||
|
||||
|
||||
struct llvmpipe_context;
|
||||
struct quad_header;
|
||||
|
||||
|
||||
/**
|
||||
* Fragment processing is performed on 2x2 blocks of pixels called "quads".
|
||||
* Quad processing is performed with a pipeline of stages represented by
|
||||
* this type.
|
||||
*/
|
||||
struct quad_stage {
|
||||
struct llvmpipe_context *llvmpipe;
|
||||
|
||||
struct quad_stage *next;
|
||||
|
||||
void (*begin)(struct quad_stage *qs);
|
||||
|
||||
/** the stage action */
|
||||
void (*run)(struct quad_stage *qs, struct quad_header *quad);
|
||||
|
||||
void (*destroy)(struct quad_stage *qs);
|
||||
};
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_polygon_stipple_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_earlyz_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_shade_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_alpha_test_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_stencil_test_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_depth_test_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_occlusion_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_coverage_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_blend_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_colormask_stage( struct llvmpipe_context *llvmpipe );
|
||||
struct quad_stage *lp_quad_output_stage( struct llvmpipe_context *llvmpipe );
|
||||
|
||||
void lp_build_quad_pipeline(struct llvmpipe_context *lp);
|
||||
|
||||
void lp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad);
|
||||
|
||||
#endif /* SP_QUAD_PIPE_H */
|
||||
352
src/gallium/drivers/llvmpipe/lp_quad_stencil.c
Normal file
352
src/gallium/drivers/llvmpipe/lp_quad_stencil.c
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
|
||||
/**
|
||||
* \brief Quad stencil testing
|
||||
*/
|
||||
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
/** Only 8-bit stencil supported */
|
||||
#define STENCIL_MAX 0xff
|
||||
|
||||
|
||||
/**
|
||||
* Do the basic stencil test (compare stencil buffer values against the
|
||||
* reference value.
|
||||
*
|
||||
* \param stencilVals the stencil values from the stencil buffer
|
||||
* \param func the stencil func (PIPE_FUNC_x)
|
||||
* \param ref the stencil reference value
|
||||
* \param valMask the stencil value mask indicating which bits of the stencil
|
||||
* values and ref value are to be used.
|
||||
* \return mask indicating which pixels passed the stencil test
|
||||
*/
|
||||
static unsigned
|
||||
do_stencil_test(const ubyte stencilVals[QUAD_SIZE], unsigned func,
|
||||
unsigned ref, unsigned valMask)
|
||||
{
|
||||
unsigned passMask = 0x0;
|
||||
unsigned j;
|
||||
|
||||
ref &= valMask;
|
||||
|
||||
switch (func) {
|
||||
case PIPE_FUNC_NEVER:
|
||||
/* passMask = 0x0 */
|
||||
break;
|
||||
case PIPE_FUNC_LESS:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref < (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_EQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref == (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_LEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref <= (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GREATER:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref > (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_NOTEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref != (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_GEQUAL:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (ref >= (stencilVals[j] & valMask)) {
|
||||
passMask |= (1 << j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FUNC_ALWAYS:
|
||||
passMask = MASK_ALL;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return passMask;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply the stencil operator to stencil values.
|
||||
*
|
||||
* \param stencilVals the stencil buffer values (read and written)
|
||||
* \param mask indicates which pixels to update
|
||||
* \param op the stencil operator (PIPE_STENCIL_OP_x)
|
||||
* \param ref the stencil reference value
|
||||
* \param wrtMask writemask controlling which bits are changed in the
|
||||
* stencil values
|
||||
*/
|
||||
static void
|
||||
apply_stencil_op(ubyte stencilVals[QUAD_SIZE],
|
||||
unsigned mask, unsigned op, ubyte ref, ubyte wrtMask)
|
||||
{
|
||||
unsigned j;
|
||||
ubyte newstencil[QUAD_SIZE];
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
newstencil[j] = stencilVals[j];
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case PIPE_STENCIL_OP_KEEP:
|
||||
/* no-op */
|
||||
break;
|
||||
case PIPE_STENCIL_OP_ZERO:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_REPLACE:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = ref;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INCR:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
if (stencilVals[j] < STENCIL_MAX) {
|
||||
newstencil[j] = stencilVals[j] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_DECR:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
if (stencilVals[j] > 0) {
|
||||
newstencil[j] = stencilVals[j] - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INCR_WRAP:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = stencilVals[j] + 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_DECR_WRAP:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = stencilVals[j] - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_STENCIL_OP_INVERT:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
if (mask & (1 << j)) {
|
||||
newstencil[j] = ~stencilVals[j];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* update the stencil values
|
||||
*/
|
||||
if (wrtMask != STENCIL_MAX) {
|
||||
/* apply bit-wise stencil buffer writemask */
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
stencilVals[j] = newstencil[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Do stencil (and depth) testing. Stenciling depends on the outcome of
|
||||
* depth testing.
|
||||
*/
|
||||
static void
|
||||
stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf;
|
||||
unsigned func, zFailOp, zPassOp, failOp;
|
||||
ubyte ref, wrtMask, valMask;
|
||||
ubyte stencilVals[QUAD_SIZE];
|
||||
struct llvmpipe_cached_tile *tile
|
||||
= lp_get_cached_tile(llvmpipe, llvmpipe->zsbuf_cache, quad->input.x0, quad->input.y0);
|
||||
uint j;
|
||||
uint face = quad->input.facing;
|
||||
|
||||
if (!llvmpipe->depth_stencil->stencil[1].enabled) {
|
||||
/* single-sided stencil test, use front (face=0) state */
|
||||
face = 0;
|
||||
}
|
||||
|
||||
/* choose front or back face function, operator, etc */
|
||||
/* XXX we could do these initializations once per primitive */
|
||||
func = llvmpipe->depth_stencil->stencil[face].func;
|
||||
failOp = llvmpipe->depth_stencil->stencil[face].fail_op;
|
||||
zFailOp = llvmpipe->depth_stencil->stencil[face].zfail_op;
|
||||
zPassOp = llvmpipe->depth_stencil->stencil[face].zpass_op;
|
||||
ref = llvmpipe->depth_stencil->stencil[face].ref_value;
|
||||
wrtMask = llvmpipe->depth_stencil->stencil[face].writemask;
|
||||
valMask = llvmpipe->depth_stencil->stencil[face].valuemask;
|
||||
|
||||
assert(ps); /* shouldn't get here if there's no stencil buffer */
|
||||
|
||||
/* get stencil values from cached tile */
|
||||
switch (ps->format) {
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
stencilVals[j] = tile->data.depth32[y][x] >> 24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
stencilVals[j] = tile->data.depth32[y][x] & 0xff;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_S8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
stencilVals[j] = tile->data.stencil8[y][x];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* do the stencil test first */
|
||||
{
|
||||
unsigned passMask, failMask;
|
||||
passMask = do_stencil_test(stencilVals, func, ref, valMask);
|
||||
failMask = quad->inout.mask & ~passMask;
|
||||
quad->inout.mask &= passMask;
|
||||
|
||||
if (failOp != PIPE_STENCIL_OP_KEEP) {
|
||||
apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask);
|
||||
}
|
||||
}
|
||||
|
||||
if (quad->inout.mask) {
|
||||
/* now the pixels that passed the stencil test are depth tested */
|
||||
if (llvmpipe->depth_stencil->depth.enabled) {
|
||||
const unsigned origMask = quad->inout.mask;
|
||||
|
||||
lp_depth_test_quad(qs, quad); /* quad->mask is updated */
|
||||
|
||||
/* update stencil buffer values according to z pass/fail result */
|
||||
if (zFailOp != PIPE_STENCIL_OP_KEEP) {
|
||||
const unsigned failMask = origMask & ~quad->inout.mask;
|
||||
apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask);
|
||||
}
|
||||
|
||||
if (zPassOp != PIPE_STENCIL_OP_KEEP) {
|
||||
const unsigned passMask = origMask & quad->inout.mask;
|
||||
apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* no depth test, apply Zpass operator to stencil buffer values */
|
||||
apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* put new stencil values into cached tile */
|
||||
switch (ps->format) {
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
uint s8z24 = tile->data.depth32[y][x];
|
||||
s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff);
|
||||
tile->data.depth32[y][x] = s8z24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
uint z24s8 = tile->data.depth32[y][x];
|
||||
z24s8 = (z24s8 & 0xffffff00) | stencilVals[j];
|
||||
tile->data.depth32[y][x] = z24s8;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_S8_UNORM:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->input.x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->input.y0 % TILE_SIZE + (j >> 1);
|
||||
tile->data.stencil8[y][x] = stencilVals[j];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
if (quad->inout.mask)
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void stencil_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void stencil_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *lp_quad_stencil_test_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = stencil_begin;
|
||||
stage->run = stencil_test_quad;
|
||||
stage->destroy = stencil_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
77
src/gallium/drivers/llvmpipe/lp_quad_stipple.c
Normal file
77
src/gallium/drivers/llvmpipe/lp_quad_stipple.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
|
||||
/**
|
||||
* quad polygon stipple stage
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_quad.h"
|
||||
#include "lp_quad_pipe.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
/**
|
||||
* Apply polygon stipple to quads produced by triangle rasterization
|
||||
*/
|
||||
static void
|
||||
stipple_quad(struct quad_stage *qs, struct quad_header *quad)
|
||||
{
|
||||
static const uint bit31 = 1 << 31;
|
||||
static const uint bit30 = 1 << 30;
|
||||
|
||||
if (quad->input.prim == QUAD_PRIM_TRI) {
|
||||
struct llvmpipe_context *llvmpipe = qs->llvmpipe;
|
||||
/* need to invert Y to index into OpenGL's stipple pattern */
|
||||
const int col0 = quad->input.x0 % 32;
|
||||
const int y0 = quad->input.y0;
|
||||
const int y1 = y0 + 1;
|
||||
const uint stipple0 = llvmpipe->poly_stipple.stipple[y0 % 32];
|
||||
const uint stipple1 = llvmpipe->poly_stipple.stipple[y1 % 32];
|
||||
|
||||
/* turn off quad mask bits that fail the stipple test */
|
||||
if ((stipple0 & (bit31 >> col0)) == 0)
|
||||
quad->inout.mask &= ~MASK_TOP_LEFT;
|
||||
|
||||
if ((stipple0 & (bit30 >> col0)) == 0)
|
||||
quad->inout.mask &= ~MASK_TOP_RIGHT;
|
||||
|
||||
if ((stipple1 & (bit31 >> col0)) == 0)
|
||||
quad->inout.mask &= ~MASK_BOTTOM_LEFT;
|
||||
|
||||
if ((stipple1 & (bit30 >> col0)) == 0)
|
||||
quad->inout.mask &= ~MASK_BOTTOM_RIGHT;
|
||||
|
||||
if (!quad->inout.mask) {
|
||||
/* all fragments failed stipple test, end of quad pipeline */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
qs->next->run(qs->next, quad);
|
||||
}
|
||||
|
||||
|
||||
static void stipple_begin(struct quad_stage *qs)
|
||||
{
|
||||
qs->next->begin(qs->next);
|
||||
}
|
||||
|
||||
|
||||
static void stipple_destroy(struct quad_stage *qs)
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
|
||||
struct quad_stage *
|
||||
lp_quad_polygon_stipple_stage( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
|
||||
|
||||
stage->llvmpipe = llvmpipe;
|
||||
stage->begin = stipple_begin;
|
||||
stage->run = stipple_quad;
|
||||
stage->destroy = stipple_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
111
src/gallium/drivers/llvmpipe/lp_query.c
Normal file
111
src/gallium/drivers/llvmpipe/lp_query.c
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_query.h"
|
||||
#include "lp_state.h"
|
||||
|
||||
struct llvmpipe_query {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
};
|
||||
|
||||
|
||||
static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p )
|
||||
{
|
||||
return (struct llvmpipe_query *)p;
|
||||
}
|
||||
|
||||
static struct pipe_query *
|
||||
llvmpipe_create_query(struct pipe_context *pipe,
|
||||
unsigned type)
|
||||
{
|
||||
assert(type == PIPE_QUERY_OCCLUSION_COUNTER);
|
||||
return (struct pipe_query *)CALLOC_STRUCT( llvmpipe_query );
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
|
||||
{
|
||||
FREE(q);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
|
||||
struct llvmpipe_query *sq = llvmpipe_query(q);
|
||||
|
||||
sq->start = llvmpipe->occlusion_count;
|
||||
llvmpipe->active_query_count++;
|
||||
llvmpipe->dirty |= SP_NEW_QUERY;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
|
||||
struct llvmpipe_query *sq = llvmpipe_query(q);
|
||||
|
||||
llvmpipe->active_query_count--;
|
||||
sq->end = llvmpipe->occlusion_count;
|
||||
llvmpipe->dirty |= SP_NEW_QUERY;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
llvmpipe_get_query_result(struct pipe_context *pipe,
|
||||
struct pipe_query *q,
|
||||
boolean wait,
|
||||
uint64_t *result )
|
||||
{
|
||||
struct llvmpipe_query *sq = llvmpipe_query(q);
|
||||
*result = sq->end - sq->start;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
llvmpipe->pipe.create_query = llvmpipe_create_query;
|
||||
llvmpipe->pipe.destroy_query = llvmpipe_destroy_query;
|
||||
llvmpipe->pipe.begin_query = llvmpipe_begin_query;
|
||||
llvmpipe->pipe.end_query = llvmpipe_end_query;
|
||||
llvmpipe->pipe.get_query_result = llvmpipe_get_query_result;
|
||||
}
|
||||
|
||||
|
||||
39
src/gallium/drivers/llvmpipe/lp_query.h
Normal file
39
src/gallium/drivers/llvmpipe/lp_query.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef SP_QUERY_H
|
||||
#define SP_QUERY_H
|
||||
|
||||
struct llvmpipe_context;
|
||||
extern void llvmpipe_init_query_funcs(struct llvmpipe_context * );
|
||||
|
||||
|
||||
#endif /* SP_QUERY_H */
|
||||
190
src/gallium/drivers/llvmpipe/lp_screen.c
Normal file
190
src/gallium/drivers/llvmpipe/lp_screen.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_simple_screen.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
#include "lp_texture.h"
|
||||
#include "lp_winsys.h"
|
||||
#include "lp_screen.h"
|
||||
|
||||
|
||||
static const char *
|
||||
llvmpipe_get_vendor(struct pipe_screen *screen)
|
||||
{
|
||||
return "Tungsten Graphics, Inc.";
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
llvmpipe_get_name(struct pipe_screen *screen)
|
||||
{
|
||||
return "llvmpipe";
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
llvmpipe_get_param(struct pipe_screen *screen, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
|
||||
return PIPE_MAX_SAMPLERS;
|
||||
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
|
||||
return PIPE_MAX_SAMPLERS;
|
||||
case PIPE_CAP_NPOT_TEXTURES:
|
||||
return 1;
|
||||
case PIPE_CAP_TWO_SIDED_STENCIL:
|
||||
return 1;
|
||||
case PIPE_CAP_GLSL:
|
||||
return 1;
|
||||
case PIPE_CAP_S3TC:
|
||||
return 0;
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
return 0;
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
return PIPE_MAX_COLOR_BUFS;
|
||||
case PIPE_CAP_OCCLUSION_QUERY:
|
||||
return 1;
|
||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
||||
return 1;
|
||||
case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
|
||||
return 1;
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 1;
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
return 13; /* max 4Kx4K */
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 8; /* max 128x128x128 */
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return 13; /* max 4Kx4K */
|
||||
case PIPE_CAP_TGSI_CONT_SUPPORTED:
|
||||
return 1;
|
||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
llvmpipe_get_paramf(struct pipe_screen *screen, int param)
|
||||
{
|
||||
switch (param) {
|
||||
case PIPE_CAP_MAX_LINE_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_LINE_WIDTH_AA:
|
||||
return 255.0; /* arbitrary */
|
||||
case PIPE_CAP_MAX_POINT_WIDTH:
|
||||
/* fall-through */
|
||||
case PIPE_CAP_MAX_POINT_WIDTH_AA:
|
||||
return 255.0; /* arbitrary */
|
||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
||||
return 16.0; /* not actually signficant at this time */
|
||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0; /* arbitrary */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query format support for creating a texture, drawing surface, etc.
|
||||
* \param format the format to test
|
||||
* \param type one of PIPE_TEXTURE, PIPE_SURFACE
|
||||
*/
|
||||
static boolean
|
||||
llvmpipe_is_format_supported( struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned tex_usage,
|
||||
unsigned geom_flags )
|
||||
{
|
||||
assert(target == PIPE_TEXTURE_1D ||
|
||||
target == PIPE_TEXTURE_2D ||
|
||||
target == PIPE_TEXTURE_3D ||
|
||||
target == PIPE_TEXTURE_CUBE);
|
||||
|
||||
switch(format) {
|
||||
case PIPE_FORMAT_DXT1_RGB:
|
||||
case PIPE_FORMAT_DXT1_RGBA:
|
||||
case PIPE_FORMAT_DXT3_RGBA:
|
||||
case PIPE_FORMAT_DXT5_RGBA:
|
||||
return FALSE;
|
||||
default:
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_destroy_screen( struct pipe_screen *screen )
|
||||
{
|
||||
struct pipe_winsys *winsys = screen->winsys;
|
||||
|
||||
if(winsys->destroy)
|
||||
winsys->destroy(winsys);
|
||||
|
||||
FREE(screen);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new pipe_screen object
|
||||
* Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
|
||||
*/
|
||||
struct pipe_screen *
|
||||
llvmpipe_create_screen(struct pipe_winsys *winsys)
|
||||
{
|
||||
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
screen->base.winsys = winsys;
|
||||
|
||||
screen->base.destroy = llvmpipe_destroy_screen;
|
||||
|
||||
screen->base.get_name = llvmpipe_get_name;
|
||||
screen->base.get_vendor = llvmpipe_get_vendor;
|
||||
screen->base.get_param = llvmpipe_get_param;
|
||||
screen->base.get_paramf = llvmpipe_get_paramf;
|
||||
screen->base.is_format_supported = llvmpipe_is_format_supported;
|
||||
|
||||
llvmpipe_init_screen_texture_funcs(&screen->base);
|
||||
u_simple_screen_init(&screen->base);
|
||||
|
||||
return &screen->base;
|
||||
}
|
||||
58
src/gallium/drivers/llvmpipe/lp_screen.h
Normal file
58
src/gallium/drivers/llvmpipe/lp_screen.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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_SCREEN_H
|
||||
#define SP_SCREEN_H
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_defines.h"
|
||||
|
||||
|
||||
|
||||
struct llvmpipe_screen {
|
||||
struct pipe_screen base;
|
||||
|
||||
/* Increments whenever textures are modified. Contexts can track
|
||||
* this.
|
||||
*/
|
||||
unsigned timestamp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static INLINE struct llvmpipe_screen *
|
||||
llvmpipe_screen( struct pipe_screen *pipe )
|
||||
{
|
||||
return (struct llvmpipe_screen *)pipe;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SP_SCREEN_H */
|
||||
1550
src/gallium/drivers/llvmpipe/lp_setup.c
Normal file
1550
src/gallium/drivers/llvmpipe/lp_setup.c
Normal file
File diff suppressed because it is too large
Load diff
53
src/gallium/drivers/llvmpipe/lp_setup.h
Normal file
53
src/gallium/drivers/llvmpipe/lp_setup.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
#ifndef SP_SETUP_H
|
||||
#define SP_SETUP_H
|
||||
|
||||
struct setup_context;
|
||||
struct llvmpipe_context;
|
||||
|
||||
void
|
||||
setup_tri( struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4],
|
||||
const float (*v2)[4] );
|
||||
|
||||
void
|
||||
setup_line(struct setup_context *setup,
|
||||
const float (*v0)[4],
|
||||
const float (*v1)[4]);
|
||||
|
||||
void
|
||||
setup_point( struct setup_context *setup,
|
||||
const float (*v0)[4] );
|
||||
|
||||
|
||||
struct setup_context *setup_create_context( struct llvmpipe_context *llvmpipe );
|
||||
void setup_prepare( struct setup_context *setup );
|
||||
void setup_destroy_context( struct setup_context *setup );
|
||||
|
||||
#endif
|
||||
206
src/gallium/drivers/llvmpipe/lp_state.h
Normal file
206
src/gallium/drivers/llvmpipe/lp_state.h
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef SP_STATE_H
|
||||
#define SP_STATE_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
#include "tgsi/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;
|
||||
struct vertex_info;
|
||||
|
||||
|
||||
/**
|
||||
* 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 lp_fragment_shader {
|
||||
struct pipe_shader_state shader;
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
void (*prepare)( const struct lp_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 lp_fragment_shader *shader,
|
||||
struct tgsi_exec_machine *machine,
|
||||
struct quad_header *quad );
|
||||
|
||||
|
||||
void (*delete)( struct lp_fragment_shader * );
|
||||
};
|
||||
|
||||
|
||||
/** Subclass of pipe_shader_state */
|
||||
struct lp_vertex_shader {
|
||||
struct pipe_shader_state shader;
|
||||
struct draw_vertex_shader *draw_data;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_blend_state(struct pipe_context *,
|
||||
const struct pipe_blend_state *);
|
||||
void llvmpipe_bind_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
void llvmpipe_delete_blend_state(struct pipe_context *,
|
||||
void *);
|
||||
|
||||
void *
|
||||
llvmpipe_create_sampler_state(struct pipe_context *,
|
||||
const struct pipe_sampler_state *);
|
||||
void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
|
||||
void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
llvmpipe_create_depth_stencil_state(struct pipe_context *,
|
||||
const struct pipe_depth_stencil_alpha_state *);
|
||||
void llvmpipe_bind_depth_stencil_state(struct pipe_context *, void *);
|
||||
void llvmpipe_delete_depth_stencil_state(struct pipe_context *, void *);
|
||||
|
||||
void *
|
||||
llvmpipe_create_rasterizer_state(struct pipe_context *,
|
||||
const struct pipe_rasterizer_state *);
|
||||
void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *);
|
||||
void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *);
|
||||
|
||||
void llvmpipe_set_framebuffer_state( struct pipe_context *,
|
||||
const struct pipe_framebuffer_state * );
|
||||
|
||||
void llvmpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color );
|
||||
|
||||
void llvmpipe_set_clip_state( struct pipe_context *,
|
||||
const struct pipe_clip_state * );
|
||||
|
||||
void llvmpipe_set_constant_buffer(struct pipe_context *,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf);
|
||||
|
||||
void *llvmpipe_create_fs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void llvmpipe_bind_fs_state(struct pipe_context *, void *);
|
||||
void llvmpipe_delete_fs_state(struct pipe_context *, void *);
|
||||
void *llvmpipe_create_vs_state(struct pipe_context *,
|
||||
const struct pipe_shader_state *);
|
||||
void llvmpipe_bind_vs_state(struct pipe_context *, void *);
|
||||
void llvmpipe_delete_vs_state(struct pipe_context *, void *);
|
||||
|
||||
void llvmpipe_set_polygon_stipple( struct pipe_context *,
|
||||
const struct pipe_poly_stipple * );
|
||||
|
||||
void llvmpipe_set_scissor_state( struct pipe_context *,
|
||||
const struct pipe_scissor_state * );
|
||||
|
||||
void llvmpipe_set_sampler_textures( struct pipe_context *,
|
||||
unsigned num,
|
||||
struct pipe_texture ** );
|
||||
|
||||
void llvmpipe_set_viewport_state( struct pipe_context *,
|
||||
const struct pipe_viewport_state * );
|
||||
|
||||
void llvmpipe_set_vertex_elements(struct pipe_context *,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *);
|
||||
|
||||
void llvmpipe_set_vertex_buffers(struct pipe_context *,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_buffer *);
|
||||
|
||||
|
||||
void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe );
|
||||
|
||||
|
||||
boolean llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
|
||||
unsigned start, unsigned count);
|
||||
|
||||
boolean llvmpipe_draw_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned mode, unsigned start, unsigned count);
|
||||
boolean
|
||||
llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
struct pipe_buffer *indexBuffer,
|
||||
unsigned indexSize,
|
||||
unsigned min_index,
|
||||
unsigned max_index,
|
||||
unsigned mode, unsigned start, unsigned count);
|
||||
|
||||
void
|
||||
llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_map_transfers(struct llvmpipe_context *lp);
|
||||
|
||||
void
|
||||
llvmpipe_unmap_transfers(struct llvmpipe_context *lp);
|
||||
|
||||
void
|
||||
llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp);
|
||||
|
||||
void
|
||||
llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp);
|
||||
|
||||
|
||||
struct vertex_info *
|
||||
llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe);
|
||||
|
||||
struct vertex_info *
|
||||
llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe);
|
||||
|
||||
|
||||
#endif
|
||||
98
src/gallium/drivers/llvmpipe/lp_state_blend.c
Normal file
98
src/gallium/drivers/llvmpipe/lp_state_blend.c
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
return mem_dup(blend, sizeof(*blend));
|
||||
}
|
||||
|
||||
void llvmpipe_bind_blend_state( struct pipe_context *pipe,
|
||||
void *blend )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->blend = (const struct pipe_blend_state *)blend;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_BLEND;
|
||||
}
|
||||
|
||||
void llvmpipe_delete_blend_state(struct pipe_context *pipe,
|
||||
void *blend)
|
||||
{
|
||||
FREE( blend );
|
||||
}
|
||||
|
||||
|
||||
void llvmpipe_set_blend_color( struct pipe_context *pipe,
|
||||
const struct pipe_blend_color *blend_color )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->blend_color = *blend_color;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_BLEND;
|
||||
}
|
||||
|
||||
|
||||
/** XXX move someday? Or consolidate all these simple state setters
|
||||
* into one file.
|
||||
*/
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_depth_stencil_state(struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *depth_stencil)
|
||||
{
|
||||
return mem_dup(depth_stencil, sizeof(*depth_stencil));
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
|
||||
void *depth_stencil)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA;
|
||||
}
|
||||
|
||||
void
|
||||
llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
|
||||
{
|
||||
FREE( depth );
|
||||
}
|
||||
79
src/gallium/drivers/llvmpipe/lp_state_clip.c
Normal file
79
src/gallium/drivers/llvmpipe/lp_state_clip.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
void llvmpipe_set_clip_state( struct pipe_context *pipe,
|
||||
const struct pipe_clip_state *clip )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
/* pass the clip state to the draw module */
|
||||
draw_set_clip_state(llvmpipe->draw, clip);
|
||||
}
|
||||
|
||||
|
||||
void llvmpipe_set_viewport_state( struct pipe_context *pipe,
|
||||
const struct pipe_viewport_state *viewport )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
/* pass the viewport info to the draw module */
|
||||
draw_set_viewport_state(llvmpipe->draw, viewport);
|
||||
|
||||
llvmpipe->viewport = *viewport; /* struct copy */
|
||||
llvmpipe->dirty |= SP_NEW_VIEWPORT;
|
||||
}
|
||||
|
||||
|
||||
void llvmpipe_set_scissor_state( struct pipe_context *pipe,
|
||||
const struct pipe_scissor_state *scissor )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
llvmpipe->scissor = *scissor; /* struct copy */
|
||||
llvmpipe->dirty |= SP_NEW_SCISSOR;
|
||||
}
|
||||
|
||||
|
||||
void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
|
||||
const struct pipe_poly_stipple *stipple )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
llvmpipe->poly_stipple = *stipple; /* struct copy */
|
||||
llvmpipe->dirty |= SP_NEW_STIPPLE;
|
||||
}
|
||||
211
src/gallium/drivers/llvmpipe/lp_state_derived.c
Normal file
211
src/gallium/drivers/llvmpipe/lp_state_derived.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "draw/draw_vertex.h"
|
||||
#include "draw/draw_private.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
|
||||
|
||||
/**
|
||||
* Mark the current vertex layout as "invalid".
|
||||
* We'll validate the vertex layout later, when we start to actually
|
||||
* render a point or line or tri.
|
||||
*/
|
||||
static void
|
||||
invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
|
||||
{
|
||||
llvmpipe->vertex_info.num_attribs = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The vertex info describes how to convert the post-transformed vertices
|
||||
* (simple float[][4]) used by the 'draw' module into vertices for
|
||||
* rasterization.
|
||||
*
|
||||
* This function validates the vertex layout and returns a pointer to a
|
||||
* vertex_info object.
|
||||
*/
|
||||
struct vertex_info *
|
||||
llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
|
||||
{
|
||||
struct vertex_info *vinfo = &llvmpipe->vertex_info;
|
||||
|
||||
if (vinfo->num_attribs == 0) {
|
||||
/* compute vertex layout now */
|
||||
const struct lp_fragment_shader *lpfs = llvmpipe->fs;
|
||||
const enum interp_mode colorInterp
|
||||
= llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
|
||||
uint i;
|
||||
|
||||
if (llvmpipe->vbuf) {
|
||||
/* if using the post-transform vertex buffer, tell draw_vbuf to
|
||||
* simply emit the whole post-xform vertex as-is:
|
||||
*/
|
||||
struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
|
||||
const uint num = draw_num_vs_outputs(llvmpipe->draw);
|
||||
uint i;
|
||||
|
||||
/* No longer any need to try and emit draw vertex_header info.
|
||||
*/
|
||||
vinfo_vbuf->num_attribs = 0;
|
||||
for (i = 0; i < num; i++) {
|
||||
draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
|
||||
}
|
||||
draw_compute_vertex_size(vinfo_vbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop over fragment shader inputs, searching for the matching output
|
||||
* from the vertex shader.
|
||||
*/
|
||||
vinfo->num_attribs = 0;
|
||||
for (i = 0; i < lpfs->info.num_inputs; i++) {
|
||||
int src;
|
||||
switch (lpfs->info.input_semantic_name[i]) {
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
src = draw_find_vs_output(llvmpipe->draw,
|
||||
TGSI_SEMANTIC_POSITION, 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR,
|
||||
lpfs->info.input_semantic_index[i]);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_FOG:
|
||||
src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
case TGSI_SEMANTIC_GENERIC:
|
||||
case TGSI_SEMANTIC_FACE:
|
||||
/* this includes texcoords and varying vars */
|
||||
src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC,
|
||||
lpfs->info.input_semantic_index[i]);
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
|
||||
TGSI_SEMANTIC_PSIZE, 0);
|
||||
if (llvmpipe->psize_slot > 0) {
|
||||
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
|
||||
llvmpipe->psize_slot);
|
||||
}
|
||||
|
||||
draw_compute_vertex_size(vinfo);
|
||||
}
|
||||
|
||||
return vinfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called from vbuf module.
|
||||
*
|
||||
* Note that there's actually two different vertex layouts in llvmpipe.
|
||||
*
|
||||
* The normal one is computed in llvmpipe_get_vertex_info() above and is
|
||||
* used by the point/line/tri "setup" code.
|
||||
*
|
||||
* The other one (this one) is only used by the vbuf module (which is
|
||||
* not normally used by default but used in testing). For the vbuf module,
|
||||
* we basically want to pass-through the draw module's vertex layout as-is.
|
||||
* When the llvmpipe vbuf code begins drawing, the normal vertex layout
|
||||
* will come into play again.
|
||||
*/
|
||||
struct vertex_info *
|
||||
llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe)
|
||||
{
|
||||
(void) llvmpipe_get_vertex_info(llvmpipe);
|
||||
return &llvmpipe->vertex_info_vbuf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recompute cliprect from scissor bounds, scissor enable and surface size.
|
||||
*/
|
||||
static void
|
||||
compute_cliprect(struct llvmpipe_context *lp)
|
||||
{
|
||||
uint surfWidth = lp->framebuffer.width;
|
||||
uint surfHeight = lp->framebuffer.height;
|
||||
|
||||
if (lp->rasterizer->scissor) {
|
||||
/* clip to scissor rect */
|
||||
lp->cliprect.minx = MAX2(lp->scissor.minx, 0);
|
||||
lp->cliprect.miny = MAX2(lp->scissor.miny, 0);
|
||||
lp->cliprect.maxx = MIN2(lp->scissor.maxx, surfWidth);
|
||||
lp->cliprect.maxy = MIN2(lp->scissor.maxy, surfHeight);
|
||||
}
|
||||
else {
|
||||
/* clip to surface bounds */
|
||||
lp->cliprect.minx = 0;
|
||||
lp->cliprect.miny = 0;
|
||||
lp->cliprect.maxx = surfWidth;
|
||||
lp->cliprect.maxy = surfHeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Hopefully this will remain quite simple, otherwise need to pull in
|
||||
* something like the state tracker mechanism.
|
||||
*/
|
||||
void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
|
||||
{
|
||||
if (llvmpipe->dirty & (SP_NEW_RASTERIZER |
|
||||
SP_NEW_FS |
|
||||
SP_NEW_VS))
|
||||
invalidate_vertex_layout( llvmpipe );
|
||||
|
||||
if (llvmpipe->dirty & (SP_NEW_SCISSOR |
|
||||
SP_NEW_DEPTH_STENCIL_ALPHA |
|
||||
SP_NEW_FRAMEBUFFER))
|
||||
compute_cliprect(llvmpipe);
|
||||
|
||||
if (llvmpipe->dirty & (SP_NEW_BLEND |
|
||||
SP_NEW_DEPTH_STENCIL_ALPHA |
|
||||
SP_NEW_FRAMEBUFFER |
|
||||
SP_NEW_RASTERIZER |
|
||||
SP_NEW_FS |
|
||||
SP_NEW_QUERY))
|
||||
lp_build_quad_pipeline(llvmpipe);
|
||||
|
||||
llvmpipe->dirty = 0;
|
||||
}
|
||||
169
src/gallium/drivers/llvmpipe/lp_state_fs.c
Normal file
169
src/gallium/drivers/llvmpipe/lp_state_fs.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_fs.h"
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "pipe/internal/p_winsys_screen.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "tgsi/tgsi_dump.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_fs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
struct lp_fragment_shader *state;
|
||||
|
||||
/* debug */
|
||||
if (llvmpipe->dump_fs)
|
||||
tgsi_dump(templ->tokens, 0);
|
||||
|
||||
/* codegen */
|
||||
state = llvmpipe_create_fs_llvm( llvmpipe, templ );
|
||||
if (!state) {
|
||||
state = llvmpipe_create_fs_sse( llvmpipe, templ );
|
||||
if (!state) {
|
||||
state = llvmpipe_create_fs_exec( llvmpipe, templ );
|
||||
}
|
||||
}
|
||||
|
||||
assert(state);
|
||||
|
||||
/* get/save the summary info for this shader */
|
||||
tgsi_scan_shader(templ->tokens, &state->info);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->fs = (struct lp_fragment_shader *) fs;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_FS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
|
||||
{
|
||||
struct lp_fragment_shader *state = fs;
|
||||
|
||||
assert(fs != llvmpipe_context(pipe)->fs);
|
||||
|
||||
state->delete( state );
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_vs_state(struct pipe_context *pipe,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
struct lp_vertex_shader *state;
|
||||
|
||||
state = CALLOC_STRUCT(lp_vertex_shader);
|
||||
if (state == NULL )
|
||||
goto fail;
|
||||
|
||||
/* copy shader tokens, the ones passed in will go away.
|
||||
*/
|
||||
state->shader.tokens = tgsi_dup_tokens(templ->tokens);
|
||||
if (state->shader.tokens == NULL)
|
||||
goto fail;
|
||||
|
||||
state->draw_data = draw_create_vertex_shader(llvmpipe->draw, templ);
|
||||
if (state->draw_data == NULL)
|
||||
goto fail;
|
||||
|
||||
return state;
|
||||
|
||||
fail:
|
||||
if (state) {
|
||||
FREE( (void *)state->shader.tokens );
|
||||
FREE( state->draw_data );
|
||||
FREE( state );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->vs = (const struct lp_vertex_shader *)vs;
|
||||
|
||||
draw_bind_vertex_shader(llvmpipe->draw,
|
||||
(llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_VS;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
struct lp_vertex_shader *state =
|
||||
(struct lp_vertex_shader *)vs;
|
||||
|
||||
draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
|
||||
FREE( state );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_set_constant_buffer(struct pipe_context *pipe,
|
||||
uint shader, uint index,
|
||||
const struct pipe_constant_buffer *buf)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
|
||||
/* note: reference counting */
|
||||
pipe_buffer_reference(&llvmpipe->constants[shader].buffer,
|
||||
buf ? buf->buffer : NULL);
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_CONSTANTS;
|
||||
}
|
||||
62
src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
Normal file
62
src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
|
||||
const struct pipe_rasterizer_state *rast)
|
||||
{
|
||||
return mem_dup(rast, sizeof(*rast));
|
||||
}
|
||||
|
||||
void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
|
||||
void *setup)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
/* pass-through to draw module */
|
||||
draw_set_rasterizer_state(llvmpipe->draw, setup);
|
||||
|
||||
llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_RASTERIZER;
|
||||
}
|
||||
|
||||
void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
|
||||
void *rasterizer)
|
||||
{
|
||||
FREE( rasterizer );
|
||||
}
|
||||
|
||||
|
||||
117
src/gallium/drivers/llvmpipe/lp_state_sampler.c
Normal file
117
src/gallium/drivers/llvmpipe/lp_state_sampler.c
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
|
||||
void *
|
||||
llvmpipe_create_sampler_state(struct pipe_context *pipe,
|
||||
const struct pipe_sampler_state *sampler)
|
||||
{
|
||||
return mem_dup(sampler, sizeof(*sampler));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_bind_sampler_states(struct pipe_context *pipe,
|
||||
unsigned num, void **sampler)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
unsigned i;
|
||||
|
||||
assert(num <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
/* Check for no-op */
|
||||
if (num == llvmpipe->num_samplers &&
|
||||
!memcmp(llvmpipe->sampler, sampler, num * sizeof(void *)))
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
for (i = 0; i < num; ++i)
|
||||
llvmpipe->sampler[i] = sampler[i];
|
||||
for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
|
||||
llvmpipe->sampler[i] = NULL;
|
||||
|
||||
llvmpipe->num_samplers = num;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_SAMPLER;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_set_sampler_textures(struct pipe_context *pipe,
|
||||
unsigned num, struct pipe_texture **texture)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
uint i;
|
||||
|
||||
assert(num <= PIPE_MAX_SAMPLERS);
|
||||
|
||||
/* Check for no-op */
|
||||
if (num == llvmpipe->num_textures &&
|
||||
!memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *)))
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
|
||||
struct pipe_texture *tex = i < num ? texture[i] : NULL;
|
||||
|
||||
pipe_texture_reference(&llvmpipe->texture[i], tex);
|
||||
lp_tile_cache_set_texture(pipe, llvmpipe->tex_cache[i], tex);
|
||||
}
|
||||
|
||||
llvmpipe->num_textures = num;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_TEXTURE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_delete_sampler_state(struct pipe_context *pipe,
|
||||
void *sampler)
|
||||
{
|
||||
FREE( sampler );
|
||||
}
|
||||
|
||||
|
||||
|
||||
129
src/gallium/drivers/llvmpipe/lp_state_surface.c
Normal file
129
src/gallium/drivers/llvmpipe/lp_state_surface.c
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
/**
|
||||
* XXX this might get moved someday
|
||||
* Set the framebuffer surface info: color buffers, zbuffer, stencil buffer.
|
||||
* Here, we flush the old surfaces and update the tile cache to point to the new
|
||||
* surfaces.
|
||||
*/
|
||||
void
|
||||
llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
|
||||
const struct pipe_framebuffer_state *fb)
|
||||
{
|
||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
/* check if changing cbuf */
|
||||
if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {
|
||||
/* flush old */
|
||||
lp_flush_tile_cache(lp, lp->cbuf_cache[i]);
|
||||
|
||||
/* assign new */
|
||||
lp->framebuffer.cbufs[i] = fb->cbufs[i];
|
||||
|
||||
/* update cache */
|
||||
lp_tile_cache_set_surface(lp->cbuf_cache[i], fb->cbufs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
lp->framebuffer.nr_cbufs = fb->nr_cbufs;
|
||||
|
||||
/* zbuf changing? */
|
||||
if (lp->framebuffer.zsbuf != fb->zsbuf) {
|
||||
/* flush old */
|
||||
lp_flush_tile_cache(lp, lp->zsbuf_cache);
|
||||
|
||||
/* assign new */
|
||||
lp->framebuffer.zsbuf = fb->zsbuf;
|
||||
|
||||
/* update cache */
|
||||
lp_tile_cache_set_surface(lp->zsbuf_cache, fb->zsbuf);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX combined depth/stencil here */
|
||||
|
||||
/* sbuf changing? */
|
||||
if (lp->framebuffer.sbuf != fb->sbuf) {
|
||||
/* flush old */
|
||||
lp_flush_tile_cache(lp, lp->sbuf_cache_sep);
|
||||
|
||||
/* assign new */
|
||||
lp->framebuffer.sbuf = fb->sbuf;
|
||||
|
||||
/* update cache */
|
||||
if (fb->sbuf != fb->zbuf) {
|
||||
/* separate stencil buf */
|
||||
lp->sbuf_cache = lp->sbuf_cache_sep;
|
||||
lp_tile_cache_set_surface(lp->sbuf_cache, fb->sbuf);
|
||||
}
|
||||
else {
|
||||
/* combined depth/stencil */
|
||||
lp->sbuf_cache = lp->zbuf_cache;
|
||||
lp_tile_cache_set_surface(lp->sbuf_cache, fb->sbuf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Tell draw module how deep the Z/depth buffer is */
|
||||
{
|
||||
int depth_bits;
|
||||
double mrd;
|
||||
if (lp->framebuffer.zsbuf) {
|
||||
depth_bits = pf_get_component_bits(lp->framebuffer.zsbuf->format,
|
||||
PIPE_FORMAT_COMP_Z);
|
||||
}
|
||||
else {
|
||||
depth_bits = 0;
|
||||
}
|
||||
if (depth_bits > 16) {
|
||||
mrd = 0.0000001;
|
||||
}
|
||||
else {
|
||||
mrd = 0.00002;
|
||||
}
|
||||
draw_set_mrd(lp->draw, mrd);
|
||||
}
|
||||
|
||||
lp->framebuffer.width = fb->width;
|
||||
lp->framebuffer.height = fb->height;
|
||||
|
||||
lp->dirty |= SP_NEW_FRAMEBUFFER;
|
||||
}
|
||||
73
src/gallium/drivers/llvmpipe/lp_state_vertex.c
Normal file
73
src/gallium/drivers/llvmpipe/lp_state_vertex.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_surface.h"
|
||||
|
||||
#include "draw/draw_context.h"
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_set_vertex_elements(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_element *attribs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
assert(count <= PIPE_MAX_ATTRIBS);
|
||||
|
||||
memcpy(llvmpipe->vertex_element, attribs,
|
||||
count * sizeof(struct pipe_vertex_element));
|
||||
llvmpipe->num_vertex_elements = count;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_VERTEX;
|
||||
|
||||
draw_set_vertex_elements(llvmpipe->draw, count, attribs);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
|
||||
unsigned count,
|
||||
const struct pipe_vertex_buffer *buffers)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
assert(count <= PIPE_MAX_ATTRIBS);
|
||||
|
||||
memcpy(llvmpipe->vertex_buffer, buffers, count * sizeof(buffers[0]));
|
||||
llvmpipe->num_vertex_buffers = count;
|
||||
|
||||
llvmpipe->dirty |= SP_NEW_VERTEX;
|
||||
|
||||
draw_set_vertex_buffers(llvmpipe->draw, count, buffers);
|
||||
}
|
||||
50
src/gallium/drivers/llvmpipe/lp_surface.c
Normal file
50
src/gallium/drivers/llvmpipe/lp_surface.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "util/u_rect.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_surface.h"
|
||||
|
||||
|
||||
static void
|
||||
lp_surface_copy(struct pipe_context *pipe,
|
||||
struct pipe_surface *dest, unsigned destx, unsigned desty,
|
||||
struct pipe_surface *src, unsigned srcx, unsigned srcy,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
util_surface_copy(pipe, FALSE,
|
||||
dest, destx, desty,
|
||||
src, srcx, srcy,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void
|
||||
lp_init_surface_functions(struct llvmpipe_context *lp)
|
||||
{
|
||||
lp->pipe.surface_copy = lp_surface_copy;
|
||||
lp->pipe.surface_fill = util_surface_fill;
|
||||
}
|
||||
42
src/gallium/drivers/llvmpipe/lp_surface.h
Normal file
42
src/gallium/drivers/llvmpipe/lp_surface.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifndef SP_SURFACE_H
|
||||
#define SP_SURFACE_H
|
||||
|
||||
|
||||
struct llvmpipe_context;
|
||||
|
||||
|
||||
extern void
|
||||
lp_init_surface_functions(struct llvmpipe_context *lp);
|
||||
|
||||
|
||||
#endif /* SP_SURFACE_H */
|
||||
1295
src/gallium/drivers/llvmpipe/lp_tex_sample.c
Normal file
1295
src/gallium/drivers/llvmpipe/lp_tex_sample.c
Normal file
File diff suppressed because it is too large
Load diff
73
src/gallium/drivers/llvmpipe/lp_tex_sample.h
Normal file
73
src/gallium/drivers/llvmpipe/lp_tex_sample.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SP_TEX_SAMPLE_H
|
||||
#define SP_TEX_SAMPLE_H
|
||||
|
||||
|
||||
#include "tgsi/tgsi_exec.h"
|
||||
|
||||
|
||||
/**
|
||||
* Subclass of tgsi_sampler
|
||||
*/
|
||||
struct lp_shader_sampler
|
||||
{
|
||||
struct tgsi_sampler base; /**< base class */
|
||||
|
||||
uint unit;
|
||||
struct llvmpipe_context *lp;
|
||||
struct llvmpipe_tile_cache *cache;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static INLINE const struct lp_shader_sampler *
|
||||
lp_shader_sampler(const struct tgsi_sampler *sampler)
|
||||
{
|
||||
return (const struct lp_shader_sampler *) sampler;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
float lodbias,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE]);
|
||||
|
||||
extern void
|
||||
lp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
const float t[QUAD_SIZE],
|
||||
const float p[QUAD_SIZE],
|
||||
float lodbias,
|
||||
float rgba[NUM_CHANNELS][QUAD_SIZE]);
|
||||
|
||||
|
||||
#endif /* SP_TEX_SAMPLE_H */
|
||||
421
src/gallium/drivers/llvmpipe/lp_texture.c
Normal file
421
src/gallium/drivers/llvmpipe/lp_texture.c
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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/internal/p_winsys_screen.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_tile_cache.h"
|
||||
#include "lp_screen.h"
|
||||
#include "lp_winsys.h"
|
||||
|
||||
|
||||
/* Simple, maximally packed layout.
|
||||
*/
|
||||
|
||||
static unsigned minify( unsigned d )
|
||||
{
|
||||
return MAX2(1, d>>1);
|
||||
}
|
||||
|
||||
|
||||
/* Conventional allocation path for non-display textures:
|
||||
*/
|
||||
static boolean
|
||||
llvmpipe_texture_layout(struct pipe_screen *screen,
|
||||
struct llvmpipe_texture * lpt)
|
||||
{
|
||||
struct pipe_texture *pt = &lpt->base;
|
||||
unsigned level;
|
||||
unsigned width = pt->width[0];
|
||||
unsigned height = pt->height[0];
|
||||
unsigned depth = pt->depth[0];
|
||||
|
||||
unsigned buffer_size = 0;
|
||||
|
||||
for (level = 0; level <= pt->last_level; level++) {
|
||||
pt->width[level] = width;
|
||||
pt->height[level] = height;
|
||||
pt->depth[level] = depth;
|
||||
pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
|
||||
pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
|
||||
lpt->stride[level] = pt->nblocksx[level]*pt->block.size;
|
||||
|
||||
lpt->level_offset[level] = buffer_size;
|
||||
|
||||
buffer_size += (pt->nblocksy[level] *
|
||||
((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
|
||||
lpt->stride[level]);
|
||||
|
||||
width = minify(width);
|
||||
height = minify(height);
|
||||
depth = minify(depth);
|
||||
}
|
||||
|
||||
lpt->buffer = screen->buffer_create(screen, 32,
|
||||
PIPE_BUFFER_USAGE_PIXEL,
|
||||
buffer_size);
|
||||
|
||||
return lpt->buffer != NULL;
|
||||
}
|
||||
|
||||
static boolean
|
||||
llvmpipe_displaytarget_layout(struct pipe_screen *screen,
|
||||
struct llvmpipe_texture * lpt)
|
||||
{
|
||||
unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
|
||||
PIPE_BUFFER_USAGE_GPU_READ_WRITE);
|
||||
|
||||
lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);
|
||||
lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);
|
||||
|
||||
lpt->buffer = screen->surface_buffer_create( screen,
|
||||
lpt->base.width[0],
|
||||
lpt->base.height[0],
|
||||
lpt->base.format,
|
||||
usage,
|
||||
&lpt->stride[0]);
|
||||
|
||||
return lpt->buffer != NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
llvmpipe_texture_create(struct pipe_screen *screen,
|
||||
const struct pipe_texture *templat)
|
||||
{
|
||||
struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
|
||||
if (!lpt)
|
||||
return NULL;
|
||||
|
||||
lpt->base = *templat;
|
||||
pipe_reference_init(&lpt->base.reference, 1);
|
||||
lpt->base.screen = screen;
|
||||
|
||||
if (lpt->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
|
||||
if (!llvmpipe_displaytarget_layout(screen, lpt))
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
if (!llvmpipe_texture_layout(screen, lpt))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return &lpt->base;
|
||||
|
||||
fail:
|
||||
FREE(lpt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_texture *
|
||||
llvmpipe_texture_blanket(struct pipe_screen * screen,
|
||||
const struct pipe_texture *base,
|
||||
const unsigned *stride,
|
||||
struct pipe_buffer *buffer)
|
||||
{
|
||||
struct llvmpipe_texture *lpt;
|
||||
assert(screen);
|
||||
|
||||
/* Only supports one type */
|
||||
if (base->target != PIPE_TEXTURE_2D ||
|
||||
base->last_level != 0 ||
|
||||
base->depth[0] != 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpt = CALLOC_STRUCT(llvmpipe_texture);
|
||||
if (!lpt)
|
||||
return NULL;
|
||||
|
||||
lpt->base = *base;
|
||||
pipe_reference_init(&lpt->base.reference, 1);
|
||||
lpt->base.screen = screen;
|
||||
lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);
|
||||
lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);
|
||||
lpt->stride[0] = stride[0];
|
||||
|
||||
pipe_buffer_reference(&lpt->buffer, buffer);
|
||||
|
||||
return &lpt->base;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_texture_destroy(struct pipe_texture *pt)
|
||||
{
|
||||
struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
|
||||
|
||||
pipe_buffer_reference(&lpt->buffer, NULL);
|
||||
FREE(lpt);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_surface *
|
||||
llvmpipe_get_tex_surface(struct pipe_screen *screen,
|
||||
struct pipe_texture *pt,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
unsigned usage)
|
||||
{
|
||||
struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
|
||||
struct pipe_surface *ps;
|
||||
|
||||
assert(level <= pt->last_level);
|
||||
|
||||
ps = CALLOC_STRUCT(pipe_surface);
|
||||
if (ps) {
|
||||
pipe_reference_init(&ps->reference, 1);
|
||||
pipe_texture_reference(&ps->texture, pt);
|
||||
ps->format = pt->format;
|
||||
ps->width = pt->width[level];
|
||||
ps->height = pt->height[level];
|
||||
ps->offset = lpt->level_offset[level];
|
||||
ps->usage = usage;
|
||||
|
||||
/* Because we are llvmpipe, anything that the state tracker
|
||||
* thought was going to be done with the GPU will actually get
|
||||
* done with the CPU. Let's adjust the flags to take that into
|
||||
* account.
|
||||
*/
|
||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
|
||||
/* GPU_WRITE means "render" and that can involve reads (blending) */
|
||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ;
|
||||
}
|
||||
|
||||
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
|
||||
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
|
||||
|
||||
if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE)) {
|
||||
/* Mark the surface as dirty. The tile cache will look for this. */
|
||||
lpt->modified = TRUE;
|
||||
}
|
||||
|
||||
ps->face = face;
|
||||
ps->level = level;
|
||||
ps->zslice = zslice;
|
||||
|
||||
if (pt->target == PIPE_TEXTURE_CUBE) {
|
||||
ps->offset += face * pt->nblocksy[level] * lpt->stride[level];
|
||||
}
|
||||
else if (pt->target == PIPE_TEXTURE_3D) {
|
||||
ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level];
|
||||
}
|
||||
else {
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
|
||||
{
|
||||
/* Effectively do the texture_update work here - if texture images
|
||||
* needed post-processing to put them into hardware layout, this is
|
||||
* where it would happen. For llvmpipe, nothing to do.
|
||||
*/
|
||||
assert(surf->texture);
|
||||
pipe_texture_reference(&surf->texture, NULL);
|
||||
FREE(surf);
|
||||
}
|
||||
|
||||
|
||||
static struct pipe_transfer *
|
||||
llvmpipe_get_tex_transfer(struct pipe_screen *screen,
|
||||
struct pipe_texture *texture,
|
||||
unsigned face, unsigned level, unsigned zslice,
|
||||
enum pipe_transfer_usage usage,
|
||||
unsigned x, unsigned y, unsigned w, unsigned h)
|
||||
{
|
||||
struct llvmpipe_texture *lptex = llvmpipe_texture(texture);
|
||||
struct llvmpipe_transfer *lpt;
|
||||
|
||||
assert(texture);
|
||||
assert(level <= texture->last_level);
|
||||
|
||||
lpt = CALLOC_STRUCT(llvmpipe_transfer);
|
||||
if (lpt) {
|
||||
struct pipe_transfer *pt = &lpt->base;
|
||||
pipe_texture_reference(&pt->texture, texture);
|
||||
pt->format = texture->format;
|
||||
pt->block = texture->block;
|
||||
pt->x = x;
|
||||
pt->y = y;
|
||||
pt->width = w;
|
||||
pt->height = h;
|
||||
pt->nblocksx = texture->nblocksx[level];
|
||||
pt->nblocksy = texture->nblocksy[level];
|
||||
pt->stride = lptex->stride[level];
|
||||
pt->usage = usage;
|
||||
pt->face = face;
|
||||
pt->level = level;
|
||||
pt->zslice = zslice;
|
||||
|
||||
lpt->offset = lptex->level_offset[level];
|
||||
|
||||
if (texture->target == PIPE_TEXTURE_CUBE) {
|
||||
lpt->offset += face * pt->nblocksy * pt->stride;
|
||||
}
|
||||
else if (texture->target == PIPE_TEXTURE_3D) {
|
||||
lpt->offset += zslice * pt->nblocksy * pt->stride;
|
||||
}
|
||||
else {
|
||||
assert(face == 0);
|
||||
assert(zslice == 0);
|
||||
}
|
||||
return pt;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
|
||||
{
|
||||
/* Effectively do the texture_update work here - if texture images
|
||||
* needed post-processing to put them into hardware layout, this is
|
||||
* where it would happen. For llvmpipe, nothing to do.
|
||||
*/
|
||||
assert (transfer->texture);
|
||||
pipe_texture_reference(&transfer->texture, NULL);
|
||||
FREE(transfer);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
llvmpipe_transfer_map( struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer )
|
||||
{
|
||||
ubyte *map, *xfer_map;
|
||||
struct llvmpipe_texture *lpt;
|
||||
unsigned flags = 0;
|
||||
|
||||
assert(transfer->texture);
|
||||
lpt = llvmpipe_texture(transfer->texture);
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_READ) {
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
|
||||
}
|
||||
|
||||
if (transfer->usage != PIPE_TRANSFER_WRITE) {
|
||||
flags |= PIPE_BUFFER_USAGE_CPU_READ;
|
||||
}
|
||||
|
||||
map = pipe_buffer_map(screen, lpt->buffer, flags);
|
||||
if (map == NULL)
|
||||
return NULL;
|
||||
|
||||
/* May want to different things here depending on read/write nature
|
||||
* of the map:
|
||||
*/
|
||||
if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
|
||||
{
|
||||
/* Do something to notify sharing contexts of a texture change.
|
||||
* In llvmpipe, that would mean flushing the texture cache.
|
||||
*/
|
||||
llvmpipe_screen(screen)->timestamp++;
|
||||
}
|
||||
|
||||
xfer_map = map + llvmpipe_transfer(transfer)->offset +
|
||||
transfer->y / transfer->block.height * transfer->stride +
|
||||
transfer->x / transfer->block.width * transfer->block.size;
|
||||
/*printf("map = %p xfer map = %p\n", map, xfer_map);*/
|
||||
return xfer_map;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
llvmpipe_transfer_unmap(struct pipe_screen *screen,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct llvmpipe_texture *lpt;
|
||||
|
||||
assert(transfer->texture);
|
||||
lpt = llvmpipe_texture(transfer->texture);
|
||||
|
||||
pipe_buffer_unmap( screen, lpt->buffer );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_init_texture_funcs(struct llvmpipe_context *lp)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
|
||||
{
|
||||
screen->texture_create = llvmpipe_texture_create;
|
||||
screen->texture_blanket = llvmpipe_texture_blanket;
|
||||
screen->texture_destroy = llvmpipe_texture_destroy;
|
||||
|
||||
screen->get_tex_surface = llvmpipe_get_tex_surface;
|
||||
screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
|
||||
|
||||
screen->get_tex_transfer = llvmpipe_get_tex_transfer;
|
||||
screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
|
||||
screen->transfer_map = llvmpipe_transfer_map;
|
||||
screen->transfer_unmap = llvmpipe_transfer_unmap;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
llvmpipe_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride )
|
||||
{
|
||||
struct llvmpipe_texture *tex = (struct llvmpipe_texture *)texture;
|
||||
|
||||
if (!tex)
|
||||
return FALSE;
|
||||
|
||||
pipe_buffer_reference(buf, tex->buffer);
|
||||
|
||||
if (stride)
|
||||
*stride = tex->stride[0];
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
83
src/gallium/drivers/llvmpipe/lp_texture.h
Normal file
83
src/gallium/drivers/llvmpipe/lp_texture.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SP_TEXTURE_H
|
||||
#define SP_TEXTURE_H
|
||||
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
struct llvmpipe_context;
|
||||
|
||||
|
||||
struct llvmpipe_texture
|
||||
{
|
||||
struct pipe_texture base;
|
||||
|
||||
unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
|
||||
unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
|
||||
|
||||
/* The data is held here:
|
||||
*/
|
||||
struct pipe_buffer *buffer;
|
||||
|
||||
boolean modified;
|
||||
};
|
||||
|
||||
struct llvmpipe_transfer
|
||||
{
|
||||
struct pipe_transfer base;
|
||||
|
||||
unsigned long offset;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrappers */
|
||||
static INLINE struct llvmpipe_texture *
|
||||
llvmpipe_texture(struct pipe_texture *pt)
|
||||
{
|
||||
return (struct llvmpipe_texture *) pt;
|
||||
}
|
||||
|
||||
static INLINE struct llvmpipe_transfer *
|
||||
llvmpipe_transfer(struct pipe_transfer *pt)
|
||||
{
|
||||
return (struct llvmpipe_transfer *) pt;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
llvmpipe_init_texture_funcs( struct llvmpipe_context *llvmpipe );
|
||||
|
||||
extern void
|
||||
llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
|
||||
|
||||
|
||||
#endif /* SP_TEXTURE */
|
||||
626
src/gallium/drivers/llvmpipe/lp_tile_cache.c
Normal file
626
src/gallium/drivers/llvmpipe/lp_tile_cache.c
Normal file
|
|
@ -0,0 +1,626 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Texture tile caching.
|
||||
*
|
||||
* Author:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_tile.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_surface.h"
|
||||
#include "lp_texture.h"
|
||||
#include "lp_tile_cache.h"
|
||||
|
||||
#define NUM_ENTRIES 50
|
||||
|
||||
|
||||
/** XXX move these */
|
||||
#define MAX_WIDTH 2048
|
||||
#define MAX_HEIGHT 2048
|
||||
|
||||
|
||||
struct llvmpipe_tile_cache
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_surface *surface; /**< the surface we're caching */
|
||||
struct pipe_transfer *transfer;
|
||||
void *transfer_map;
|
||||
struct pipe_texture *texture; /**< if caching a texture */
|
||||
struct llvmpipe_cached_tile entries[NUM_ENTRIES];
|
||||
uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
|
||||
float clear_color[4]; /**< for color bufs */
|
||||
uint clear_val; /**< for z+stencil, or packed color clear value */
|
||||
boolean depth_stencil; /**< Is the surface a depth/stencil format? */
|
||||
|
||||
struct pipe_transfer *tex_trans;
|
||||
void *tex_trans_map;
|
||||
int tex_face, tex_level, tex_z;
|
||||
|
||||
struct llvmpipe_cached_tile tile; /**< scratch tile for clears */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the position in the cache for the tile that contains win pos (x,y).
|
||||
* We currently use a direct mapped cache so this is like a hack key.
|
||||
* At some point we should investige something more sophisticated, like
|
||||
* a LRU replacement policy.
|
||||
*/
|
||||
#define CACHE_POS(x, y) \
|
||||
(((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Is the tile at (x,y) in cleared state?
|
||||
*/
|
||||
static INLINE uint
|
||||
is_clear_flag_set(const uint *bitvec, int x, int y)
|
||||
{
|
||||
int pos, bit;
|
||||
x /= TILE_SIZE;
|
||||
y /= TILE_SIZE;
|
||||
pos = y * (MAX_WIDTH / TILE_SIZE) + x;
|
||||
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
|
||||
bit = bitvec[pos / 32] & (1 << (pos & 31));
|
||||
return bit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark the tile at (x,y) as not cleared.
|
||||
*/
|
||||
static INLINE void
|
||||
clear_clear_flag(uint *bitvec, int x, int y)
|
||||
{
|
||||
int pos;
|
||||
x /= TILE_SIZE;
|
||||
y /= TILE_SIZE;
|
||||
pos = y * (MAX_WIDTH / TILE_SIZE) + x;
|
||||
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
|
||||
bitvec[pos / 32] &= ~(1 << (pos & 31));
|
||||
}
|
||||
|
||||
|
||||
struct llvmpipe_tile_cache *
|
||||
lp_create_tile_cache( struct pipe_screen *screen )
|
||||
{
|
||||
struct llvmpipe_tile_cache *tc;
|
||||
uint pos;
|
||||
|
||||
tc = CALLOC_STRUCT( llvmpipe_tile_cache );
|
||||
if (tc) {
|
||||
tc->screen = screen;
|
||||
for (pos = 0; pos < NUM_ENTRIES; pos++) {
|
||||
tc->entries[pos].x =
|
||||
tc->entries[pos].y = -1;
|
||||
}
|
||||
}
|
||||
return tc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
struct pipe_screen *screen;
|
||||
uint pos;
|
||||
|
||||
for (pos = 0; pos < NUM_ENTRIES; pos++) {
|
||||
/*assert(tc->entries[pos].x < 0);*/
|
||||
}
|
||||
if (tc->transfer) {
|
||||
screen = tc->transfer->texture->screen;
|
||||
screen->tex_transfer_destroy(tc->transfer);
|
||||
}
|
||||
if (tc->tex_trans) {
|
||||
screen = tc->tex_trans->texture->screen;
|
||||
screen->tex_transfer_destroy(tc->tex_trans);
|
||||
}
|
||||
|
||||
FREE( tc );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the surface to cache.
|
||||
*/
|
||||
void
|
||||
lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc,
|
||||
struct pipe_surface *ps)
|
||||
{
|
||||
assert(!tc->texture);
|
||||
|
||||
if (tc->transfer) {
|
||||
struct pipe_screen *screen = tc->transfer->texture->screen;
|
||||
|
||||
if (ps == tc->surface)
|
||||
return;
|
||||
|
||||
if (tc->transfer_map) {
|
||||
screen->transfer_unmap(screen, tc->transfer);
|
||||
tc->transfer_map = NULL;
|
||||
}
|
||||
|
||||
screen->tex_transfer_destroy(tc->transfer);
|
||||
tc->transfer = NULL;
|
||||
}
|
||||
|
||||
tc->surface = ps;
|
||||
|
||||
if (ps) {
|
||||
struct pipe_screen *screen = ps->texture->screen;
|
||||
|
||||
tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
|
||||
ps->level, ps->zslice,
|
||||
PIPE_TRANSFER_READ_WRITE,
|
||||
0, 0, ps->width, ps->height);
|
||||
|
||||
tc->depth_stencil = (ps->format == PIPE_FORMAT_S8Z24_UNORM ||
|
||||
ps->format == PIPE_FORMAT_X8Z24_UNORM ||
|
||||
ps->format == PIPE_FORMAT_Z24S8_UNORM ||
|
||||
ps->format == PIPE_FORMAT_Z24X8_UNORM ||
|
||||
ps->format == PIPE_FORMAT_Z16_UNORM ||
|
||||
ps->format == PIPE_FORMAT_Z32_UNORM ||
|
||||
ps->format == PIPE_FORMAT_S8_UNORM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the transfer being cached.
|
||||
*/
|
||||
struct pipe_surface *
|
||||
lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
return tc->surface;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
if (tc->transfer && !tc->transfer_map)
|
||||
tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
|
||||
|
||||
if (tc->tex_trans && !tc->tex_trans_map)
|
||||
tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
if (tc->transfer_map) {
|
||||
tc->screen->transfer_unmap(tc->screen, tc->transfer);
|
||||
tc->transfer_map = NULL;
|
||||
}
|
||||
|
||||
if (tc->tex_trans_map) {
|
||||
tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
|
||||
tc->tex_trans_map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specify the texture to cache.
|
||||
*/
|
||||
void
|
||||
lp_tile_cache_set_texture(struct pipe_context *pipe,
|
||||
struct llvmpipe_tile_cache *tc,
|
||||
struct pipe_texture *texture)
|
||||
{
|
||||
uint i;
|
||||
|
||||
assert(!tc->transfer);
|
||||
|
||||
pipe_texture_reference(&tc->texture, texture);
|
||||
|
||||
if (tc->tex_trans) {
|
||||
struct pipe_screen *screen = tc->tex_trans->texture->screen;
|
||||
|
||||
if (tc->tex_trans_map) {
|
||||
screen->transfer_unmap(screen, tc->tex_trans);
|
||||
tc->tex_trans_map = NULL;
|
||||
}
|
||||
|
||||
screen->tex_transfer_destroy(tc->tex_trans);
|
||||
tc->tex_trans = NULL;
|
||||
}
|
||||
|
||||
/* mark as entries as invalid/empty */
|
||||
/* XXX we should try to avoid this when the teximage hasn't changed */
|
||||
for (i = 0; i < NUM_ENTRIES; i++) {
|
||||
tc->entries[i].x = -1;
|
||||
}
|
||||
|
||||
tc->tex_face = -1; /* any invalid value here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set pixels in a tile to the given clear color/value, float.
|
||||
*/
|
||||
static void
|
||||
clear_tile_rgba(struct llvmpipe_cached_tile *tile,
|
||||
enum pipe_format format,
|
||||
const float clear_value[4])
|
||||
{
|
||||
if (clear_value[0] == 0.0 &&
|
||||
clear_value[1] == 0.0 &&
|
||||
clear_value[2] == 0.0 &&
|
||||
clear_value[3] == 0.0) {
|
||||
memset(tile->data.color, 0, sizeof(tile->data.color));
|
||||
}
|
||||
else {
|
||||
uint i, j;
|
||||
for (i = 0; i < TILE_SIZE; i++) {
|
||||
for (j = 0; j < TILE_SIZE; j++) {
|
||||
tile->data.color[i][j][0] = clear_value[0];
|
||||
tile->data.color[i][j][1] = clear_value[1];
|
||||
tile->data.color[i][j][2] = clear_value[2];
|
||||
tile->data.color[i][j][3] = clear_value[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a tile to a solid value/color.
|
||||
*/
|
||||
static void
|
||||
clear_tile(struct llvmpipe_cached_tile *tile,
|
||||
enum pipe_format format,
|
||||
uint clear_value)
|
||||
{
|
||||
uint i, j;
|
||||
|
||||
switch (pf_get_size(format)) {
|
||||
case 1:
|
||||
memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE);
|
||||
break;
|
||||
case 2:
|
||||
if (clear_value == 0) {
|
||||
memset(tile->data.any, 0, 2 * TILE_SIZE * TILE_SIZE);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < TILE_SIZE; i++) {
|
||||
for (j = 0; j < TILE_SIZE; j++) {
|
||||
tile->data.depth16[i][j] = (ushort) clear_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (clear_value == 0) {
|
||||
memset(tile->data.any, 0, 4 * TILE_SIZE * TILE_SIZE);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < TILE_SIZE; i++) {
|
||||
for (j = 0; j < TILE_SIZE; j++) {
|
||||
tile->data.color32[i][j] = clear_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Actually clear the tiles which were flagged as being in a clear state.
|
||||
*/
|
||||
static void
|
||||
lp_tile_cache_flush_clear(struct pipe_context *pipe,
|
||||
struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
struct pipe_transfer *pt = tc->transfer;
|
||||
const uint w = tc->transfer->width;
|
||||
const uint h = tc->transfer->height;
|
||||
uint x, y;
|
||||
uint numCleared = 0;
|
||||
|
||||
/* clear the scratch tile to the clear value */
|
||||
clear_tile(&tc->tile, pt->format, tc->clear_val);
|
||||
|
||||
/* push the tile to all positions marked as clear */
|
||||
for (y = 0; y < h; y += TILE_SIZE) {
|
||||
for (x = 0; x < w; x += TILE_SIZE) {
|
||||
if (is_clear_flag_set(tc->clear_flags, x, y)) {
|
||||
pipe_put_tile_raw(pt,
|
||||
x, y, TILE_SIZE, TILE_SIZE,
|
||||
tc->tile.data.color32, 0/*STRIDE*/);
|
||||
|
||||
/* do this? */
|
||||
clear_clear_flag(tc->clear_flags, x, y);
|
||||
|
||||
numCleared++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
debug_printf("num cleared: %u\n", numCleared);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flush the tile cache: write all dirty tiles back to the transfer.
|
||||
* any tiles "flagged" as cleared will be "really" cleared.
|
||||
*/
|
||||
void
|
||||
lp_flush_tile_cache(struct llvmpipe_context *llvmpipe,
|
||||
struct llvmpipe_tile_cache *tc)
|
||||
{
|
||||
struct pipe_transfer *pt = tc->transfer;
|
||||
int inuse = 0, pos;
|
||||
|
||||
if (pt) {
|
||||
/* caching a drawing transfer */
|
||||
for (pos = 0; pos < NUM_ENTRIES; pos++) {
|
||||
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
||||
if (tile->x >= 0) {
|
||||
if (tc->depth_stencil) {
|
||||
pipe_put_tile_raw(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
tile->data.depth32, 0/*STRIDE*/);
|
||||
}
|
||||
else {
|
||||
pipe_put_tile_rgba(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
(float *) tile->data.color);
|
||||
}
|
||||
tile->x = tile->y = -1; /* mark as empty */
|
||||
inuse++;
|
||||
}
|
||||
}
|
||||
|
||||
#if TILE_CLEAR_OPTIMIZATION
|
||||
lp_tile_cache_flush_clear(&llvmpipe->pipe, tc);
|
||||
#endif
|
||||
}
|
||||
else if (tc->texture) {
|
||||
/* caching a texture, mark all entries as empty */
|
||||
for (pos = 0; pos < NUM_ENTRIES; pos++) {
|
||||
tc->entries[pos].x = -1;
|
||||
}
|
||||
tc->tex_face = -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug_printf("flushed tiles in use: %d\n", inuse);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a tile from the cache.
|
||||
* \param x, y position of tile, in pixels
|
||||
*/
|
||||
struct llvmpipe_cached_tile *
|
||||
lp_get_cached_tile(struct llvmpipe_context *llvmpipe,
|
||||
struct llvmpipe_tile_cache *tc, int x, int y)
|
||||
{
|
||||
struct pipe_transfer *pt = tc->transfer;
|
||||
|
||||
/* tile pos in framebuffer: */
|
||||
const int tile_x = x & ~(TILE_SIZE - 1);
|
||||
const int tile_y = y & ~(TILE_SIZE - 1);
|
||||
|
||||
/* cache pos/entry: */
|
||||
const int pos = CACHE_POS(x, y);
|
||||
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
||||
|
||||
if (tile_x != tile->x ||
|
||||
tile_y != tile->y) {
|
||||
|
||||
if (tile->x != -1) {
|
||||
/* put dirty tile back in framebuffer */
|
||||
if (tc->depth_stencil) {
|
||||
pipe_put_tile_raw(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
tile->data.depth32, 0/*STRIDE*/);
|
||||
}
|
||||
else {
|
||||
pipe_put_tile_rgba(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
(float *) tile->data.color);
|
||||
}
|
||||
}
|
||||
|
||||
tile->x = tile_x;
|
||||
tile->y = tile_y;
|
||||
|
||||
if (is_clear_flag_set(tc->clear_flags, x, y)) {
|
||||
/* don't get tile from framebuffer, just clear it */
|
||||
if (tc->depth_stencil) {
|
||||
clear_tile(tile, pt->format, tc->clear_val);
|
||||
}
|
||||
else {
|
||||
clear_tile_rgba(tile, pt->format, tc->clear_color);
|
||||
}
|
||||
clear_clear_flag(tc->clear_flags, x, y);
|
||||
}
|
||||
else {
|
||||
/* get new tile data from transfer */
|
||||
if (tc->depth_stencil) {
|
||||
pipe_get_tile_raw(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
tile->data.depth32, 0/*STRIDE*/);
|
||||
}
|
||||
else {
|
||||
pipe_get_tile_rgba(pt,
|
||||
tile->x, tile->y, TILE_SIZE, TILE_SIZE,
|
||||
(float *) tile->data.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given the texture face, level, zslice, x and y values, compute
|
||||
* the cache entry position/index where we'd hope to find the
|
||||
* cached texture tile.
|
||||
* This is basically a direct-map cache.
|
||||
* XXX There's probably lots of ways in which we can improve this.
|
||||
*/
|
||||
static INLINE uint
|
||||
tex_cache_pos(int x, int y, int z, int face, int level)
|
||||
{
|
||||
uint entry = x + y * 9 + z * 3 + face + level * 7;
|
||||
return entry % NUM_ENTRIES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Similar to lp_get_cached_tile() but for textures.
|
||||
* Tiles are read-only and indexed with more params.
|
||||
*/
|
||||
const struct llvmpipe_cached_tile *
|
||||
lp_get_cached_tile_tex(struct llvmpipe_context *lp,
|
||||
struct llvmpipe_tile_cache *tc, int x, int y, int z,
|
||||
int face, int level)
|
||||
{
|
||||
struct pipe_screen *screen = lp->pipe.screen;
|
||||
/* tile pos in framebuffer: */
|
||||
const int tile_x = x & ~(TILE_SIZE - 1);
|
||||
const int tile_y = y & ~(TILE_SIZE - 1);
|
||||
/* cache pos/entry: */
|
||||
const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z,
|
||||
face, level);
|
||||
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
||||
|
||||
if (tc->texture) {
|
||||
struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture);
|
||||
if (lpt->modified) {
|
||||
/* texture was modified, invalidate all cached tiles */
|
||||
uint p;
|
||||
for (p = 0; p < NUM_ENTRIES; p++) {
|
||||
tile = tc->entries + p;
|
||||
tile->x = -1;
|
||||
}
|
||||
lpt->modified = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (tile_x != tile->x ||
|
||||
tile_y != tile->y ||
|
||||
z != tile->z ||
|
||||
face != tile->face ||
|
||||
level != tile->level) {
|
||||
/* cache miss */
|
||||
|
||||
#if 0
|
||||
printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos,
|
||||
x/TILE_SIZE, y/TILE_SIZE, z, face, level);
|
||||
#endif
|
||||
/* check if we need to get a new transfer */
|
||||
if (!tc->tex_trans ||
|
||||
tc->tex_face != face ||
|
||||
tc->tex_level != level ||
|
||||
tc->tex_z != z) {
|
||||
/* get new transfer (view into texture) */
|
||||
|
||||
if (tc->tex_trans) {
|
||||
if (tc->tex_trans_map) {
|
||||
tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
|
||||
tc->tex_trans_map = NULL;
|
||||
}
|
||||
|
||||
screen->tex_transfer_destroy(tc->tex_trans);
|
||||
tc->tex_trans = NULL;
|
||||
}
|
||||
|
||||
tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z,
|
||||
PIPE_TRANSFER_READ, 0, 0,
|
||||
tc->texture->width[level],
|
||||
tc->texture->height[level]);
|
||||
tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
|
||||
|
||||
tc->tex_face = face;
|
||||
tc->tex_level = level;
|
||||
tc->tex_z = z;
|
||||
}
|
||||
|
||||
/* get tile from the transfer (view into texture) */
|
||||
pipe_get_tile_rgba(tc->tex_trans,
|
||||
tile_x, tile_y, TILE_SIZE, TILE_SIZE,
|
||||
(float *) tile->data.color);
|
||||
tile->x = tile_x;
|
||||
tile->y = tile_y;
|
||||
tile->z = z;
|
||||
tile->face = face;
|
||||
tile->level = level;
|
||||
}
|
||||
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When a whole surface is being cleared to a value we can avoid
|
||||
* fetching tiles above.
|
||||
* Save the color and set a 'clearflag' for each tile of the screen.
|
||||
*/
|
||||
void
|
||||
lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba,
|
||||
uint clearValue)
|
||||
{
|
||||
uint pos;
|
||||
|
||||
tc->clear_color[0] = rgba[0];
|
||||
tc->clear_color[1] = rgba[1];
|
||||
tc->clear_color[2] = rgba[2];
|
||||
tc->clear_color[3] = rgba[3];
|
||||
|
||||
tc->clear_val = clearValue;
|
||||
|
||||
#if TILE_CLEAR_OPTIMIZATION
|
||||
/* set flags to indicate all the tiles are cleared */
|
||||
memset(tc->clear_flags, 255, sizeof(tc->clear_flags));
|
||||
#else
|
||||
/* disable the optimization */
|
||||
memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
|
||||
#endif
|
||||
|
||||
for (pos = 0; pos < NUM_ENTRIES; pos++) {
|
||||
struct llvmpipe_cached_tile *tile = tc->entries + pos;
|
||||
tile->x = tile->y = -1;
|
||||
}
|
||||
}
|
||||
106
src/gallium/drivers/llvmpipe/lp_tile_cache.h
Normal file
106
src/gallium/drivers/llvmpipe/lp_tile_cache.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef SP_TILE_CACHE_H
|
||||
#define SP_TILE_CACHE_H
|
||||
|
||||
#define TILE_CLEAR_OPTIMIZATION 1
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
|
||||
struct llvmpipe_context;
|
||||
struct llvmpipe_tile_cache;
|
||||
|
||||
|
||||
/**
|
||||
* Cache tile size (width and height). This needs to be a power of two.
|
||||
*/
|
||||
#define TILE_SIZE 64
|
||||
|
||||
|
||||
|
||||
struct llvmpipe_cached_tile
|
||||
{
|
||||
int x, y; /**< pos of tile in window coords */
|
||||
int z, face, level; /**< Extra texture indexes */
|
||||
union {
|
||||
float color[TILE_SIZE][TILE_SIZE][4];
|
||||
uint color32[TILE_SIZE][TILE_SIZE];
|
||||
uint depth32[TILE_SIZE][TILE_SIZE];
|
||||
ushort depth16[TILE_SIZE][TILE_SIZE];
|
||||
ubyte stencil8[TILE_SIZE][TILE_SIZE];
|
||||
ubyte any[1];
|
||||
} data;
|
||||
};
|
||||
|
||||
|
||||
extern struct llvmpipe_tile_cache *
|
||||
lp_create_tile_cache( struct pipe_screen *screen );
|
||||
|
||||
extern void
|
||||
lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc);
|
||||
|
||||
extern void
|
||||
lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc,
|
||||
struct pipe_surface *lps);
|
||||
|
||||
extern struct pipe_surface *
|
||||
lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc);
|
||||
|
||||
extern void
|
||||
lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc);
|
||||
|
||||
extern void
|
||||
lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc);
|
||||
|
||||
extern void
|
||||
lp_tile_cache_set_texture(struct pipe_context *pipe,
|
||||
struct llvmpipe_tile_cache *tc,
|
||||
struct pipe_texture *texture);
|
||||
|
||||
extern void
|
||||
lp_flush_tile_cache(struct llvmpipe_context *llvmpipe,
|
||||
struct llvmpipe_tile_cache *tc);
|
||||
|
||||
extern void
|
||||
lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba,
|
||||
uint clearValue);
|
||||
|
||||
extern struct llvmpipe_cached_tile *
|
||||
lp_get_cached_tile(struct llvmpipe_context *llvmpipe,
|
||||
struct llvmpipe_tile_cache *tc, int x, int y);
|
||||
|
||||
extern const struct llvmpipe_cached_tile *
|
||||
lp_get_cached_tile_tex(struct llvmpipe_context *llvmpipe,
|
||||
struct llvmpipe_tile_cache *tc, int x, int y, int z,
|
||||
int face, int level);
|
||||
|
||||
|
||||
#endif /* SP_TILE_CACHE_H */
|
||||
|
||||
65
src/gallium/drivers/llvmpipe/lp_winsys.h
Normal file
65
src/gallium/drivers/llvmpipe/lp_winsys.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/* This is the interface that llvmpipe requires any window system
|
||||
* hosting it to implement. This is the only include file in llvmpipe
|
||||
* which is public.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SP_WINSYS_H
|
||||
#define SP_WINSYS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
struct pipe_screen;
|
||||
struct pipe_winsys;
|
||||
struct pipe_context;
|
||||
|
||||
|
||||
struct pipe_context *llvmpipe_create( struct pipe_screen * );
|
||||
|
||||
|
||||
struct pipe_screen *
|
||||
llvmpipe_create_screen(struct pipe_winsys *);
|
||||
|
||||
|
||||
boolean
|
||||
llvmpipe_get_texture_buffer( struct pipe_texture *texture,
|
||||
struct pipe_buffer **buf,
|
||||
unsigned *stride );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SP_WINSYS_H */
|
||||
Loading…
Add table
Reference in a new issue