mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-02 08:50:24 +01:00
Merge branch 'upstream-gallium-0.1' into darktama-gallium-0.1
This commit is contained in:
commit
af1a388939
27 changed files with 560 additions and 392 deletions
|
|
@ -307,20 +307,6 @@ intel_batchbuffer_flush(struct intel_batchbuffer *batch)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
intel_batchbuffer_finish(struct intel_batchbuffer *batch)
|
||||
{
|
||||
struct _DriFenceObject *fence = intel_batchbuffer_flush(batch);
|
||||
if (fence) {
|
||||
driFenceReference(fence);
|
||||
driFenceFinish(fence,
|
||||
DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW,
|
||||
GL_FALSE);
|
||||
driFenceUnReference(fence);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is the only way buffers get added to the validate list.
|
||||
*/
|
||||
boolean
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ struct intel_batchbuffer *intel_batchbuffer_alloc(struct intel_context *intel);
|
|||
void intel_batchbuffer_free(struct intel_batchbuffer *batch);
|
||||
|
||||
|
||||
void intel_batchbuffer_finish(struct intel_batchbuffer *batch);
|
||||
|
||||
struct _DriFenceObject *intel_batchbuffer_flush(struct intel_batchbuffer
|
||||
*batch);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ struct intel_context;
|
|||
struct pipe_context;
|
||||
struct pipe_winsys;
|
||||
struct pipe_buffer_handle;
|
||||
struct pipe_fence;
|
||||
struct _DriBufferObject;
|
||||
struct _DriFenceObject;
|
||||
|
||||
struct pipe_winsys *
|
||||
intel_create_pipe_winsys( int fd );
|
||||
|
|
@ -66,5 +68,20 @@ pipe_bo( struct _DriBufferObject *bo )
|
|||
}
|
||||
|
||||
|
||||
/* Turn the pipe opaque buffer pointer into a dri_bufmgr opaque
|
||||
* buffer pointer...
|
||||
*/
|
||||
static INLINE struct _DriFenceObject *
|
||||
dri_fo( struct pipe_fence *bo )
|
||||
{
|
||||
return (struct _DriFenceObject *)bo;
|
||||
}
|
||||
|
||||
static INLINE struct pipe_fence *
|
||||
pipe_fo( struct _DriFenceObject *bo )
|
||||
{
|
||||
return (struct pipe_fence *)bo;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -111,19 +111,62 @@ static void intel_i915_batch_reloc( struct i915_winsys *sws,
|
|||
|
||||
|
||||
|
||||
static void intel_i915_batch_flush( struct i915_winsys *sws )
|
||||
static void
|
||||
intel_i915_batch_flush( struct i915_winsys *sws,
|
||||
struct pipe_fence **fence )
|
||||
{
|
||||
struct intel_context *intel = intel_i915_winsys(sws)->intel;
|
||||
|
||||
intel_batchbuffer_flush( intel->batch );
|
||||
// if (0) intel_i915_batch_wait_idle( sws );
|
||||
struct pipe_fence *tmp_fence;
|
||||
|
||||
tmp_fence = pipe_fo(intel_batchbuffer_flush( intel->batch ));
|
||||
|
||||
/* this also increases the fence reference count, which is not done inside
|
||||
* intel_batchbuffer_flush call above
|
||||
*/
|
||||
sws->fence_reference(sws, fence, tmp_fence);
|
||||
}
|
||||
|
||||
|
||||
static void intel_i915_batch_finish( struct i915_winsys *sws )
|
||||
static void
|
||||
intel_i915_fence_reference( struct i915_winsys *sws,
|
||||
struct pipe_fence **dst_fence,
|
||||
struct pipe_fence *src_fence )
|
||||
{
|
||||
struct intel_context *intel = intel_i915_winsys(sws)->intel;
|
||||
intel_batchbuffer_finish( intel->batch );
|
||||
struct _DriFenceObject **dri_dst_fence = (struct _DriFenceObject **)dst_fence;
|
||||
struct _DriFenceObject *dri_src_fence = (struct _DriFenceObject *)src_fence;
|
||||
|
||||
if(dri_src_fence)
|
||||
driFenceReference(dri_src_fence);
|
||||
|
||||
if(*dri_dst_fence)
|
||||
driFenceUnReference(*dri_dst_fence);
|
||||
|
||||
*dri_dst_fence = dri_src_fence;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
intel_i915_fence_is_signalled( struct i915_winsys *sws,
|
||||
struct pipe_fence *fence )
|
||||
{
|
||||
struct _DriFenceObject *dri_fence = dri_fo(fence);
|
||||
if (fence)
|
||||
return driFenceSignaled(dri_fence,
|
||||
DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
intel_i915_fence_wait( struct i915_winsys *sws,
|
||||
struct pipe_fence *fence )
|
||||
{
|
||||
struct _DriFenceObject *dri_fence = dri_fo(fence);
|
||||
if (fence)
|
||||
driFenceFinish(dri_fence,
|
||||
DRM_FENCE_TYPE_EXE | DRM_I915_FENCE_TYPE_RW,
|
||||
GL_FALSE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -143,7 +186,10 @@ intel_create_i915simple( struct intel_context *intel,
|
|||
iws->winsys.batch_dword = intel_i915_batch_dword;
|
||||
iws->winsys.batch_reloc = intel_i915_batch_reloc;
|
||||
iws->winsys.batch_flush = intel_i915_batch_flush;
|
||||
iws->winsys.batch_finish = intel_i915_batch_finish;
|
||||
iws->winsys.fence_reference = intel_i915_fence_reference;
|
||||
iws->winsys.fence_is_signalled = intel_i915_fence_is_signalled;
|
||||
iws->winsys.fence_wait = intel_i915_fence_wait;
|
||||
|
||||
iws->intel = intel;
|
||||
|
||||
/* Create the i915simple context:
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ static void validate_begin( struct draw_stage *stage )
|
|||
|
||||
/* Clip stage
|
||||
*/
|
||||
if (!draw->rasterizer->bypass_clipping)
|
||||
{
|
||||
draw->pipeline.clip->next = next;
|
||||
next = draw->pipeline.clip;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
|
||||
#include "pipe/tgsi/exec/tgsi_core.h"
|
||||
|
||||
|
||||
#define DBG 0
|
||||
|
||||
|
||||
/**
|
||||
* Fetch a float[4] vertex attribute from memory, doing format/type
|
||||
* conversion as needed.
|
||||
|
|
@ -96,7 +100,9 @@ void draw_vertex_fetch( struct draw_context *draw,
|
|||
for (j = 0; j < count; j++) {
|
||||
uint attr;
|
||||
|
||||
/*printf("fetch vertex %u: \n", j);*/
|
||||
#if DBG
|
||||
printf("fetch vertex %u: \n", j);
|
||||
#endif
|
||||
|
||||
/* loop over vertex attributes (vertex shader inputs) */
|
||||
for (attr = 0; attr < draw->vertex_shader->state->num_inputs; attr++) {
|
||||
|
|
@ -111,7 +117,9 @@ void draw_vertex_fetch( struct draw_context *draw,
|
|||
|
||||
fetch_attrib4(src, draw->vertex_element[attr].src_format, p);
|
||||
|
||||
/*printf(" %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);*/
|
||||
#if DBG
|
||||
printf(" %u: %f %f %f %f\n", attr, p[0], p[1], p[2], p[3]);
|
||||
#endif
|
||||
|
||||
/* Transform to AoS xxxx/yyyy/zzzz/wwww representation:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,11 +44,11 @@
|
|||
|
||||
#define ADVANCE_BATCH()
|
||||
|
||||
#define FLUSH_BATCH() do { \
|
||||
if (0) i915_dump_batchbuffer( i915 ); \
|
||||
i915->winsys->batch_flush( i915->winsys ); \
|
||||
i915->batch_start = NULL; \
|
||||
i915->hardware_dirty = ~0; \
|
||||
#define FLUSH_BATCH() do { \
|
||||
if (0) i915_dump_batchbuffer( i915 ); \
|
||||
i915->winsys->batch_flush( i915->winsys, &i915->last_fence ); \
|
||||
i915->batch_start = NULL; \
|
||||
i915->hardware_dirty = ~0; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ static void i915_destroy( struct pipe_context *pipe )
|
|||
|
||||
draw_destroy( i915->draw );
|
||||
|
||||
i915->winsys->fence_reference( i915->winsys, &i915->last_fence, NULL );
|
||||
|
||||
free( i915 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@
|
|||
|
||||
|
||||
|
||||
struct pipe_fence;
|
||||
struct i915_cache_context;
|
||||
|
||||
/* Use to calculate differences between state emitted to hardware and
|
||||
|
|
@ -184,6 +185,8 @@ struct i915_context
|
|||
unsigned dirty;
|
||||
|
||||
unsigned *batch_start;
|
||||
|
||||
struct pipe_fence *last_fence;
|
||||
|
||||
/** Vertex buffer */
|
||||
struct pipe_buffer_handle *vbo;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,8 @@ static void i915_flush( struct pipe_context *pipe,
|
|||
FLUSH_BATCH();
|
||||
|
||||
if (flags & PIPE_FLUSH_WAIT) {
|
||||
i915->winsys->batch_finish(i915->winsys);
|
||||
if( i915->last_fence )
|
||||
i915->winsys->fence_wait(i915->winsys, i915->last_fence);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
struct pipe_buffer_handle;
|
||||
struct pipe_winsys;
|
||||
struct pipe_fence;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -97,8 +98,28 @@ struct i915_winsys {
|
|||
unsigned access_flags,
|
||||
unsigned delta );
|
||||
|
||||
void (*batch_flush)( struct i915_winsys *sws );
|
||||
void (*batch_finish)( struct i915_winsys *sws );
|
||||
/**
|
||||
* Flush the batch buffer.
|
||||
*
|
||||
* Fence argument must point to NULL or to a previous fence, and the caller
|
||||
* must call fence_reference when done with the fence.
|
||||
*/
|
||||
void (*batch_flush)( struct i915_winsys *sws,
|
||||
struct pipe_fence **fence );
|
||||
|
||||
|
||||
/* Fence
|
||||
*/
|
||||
void (*fence_reference)( struct i915_winsys *sws,
|
||||
struct pipe_fence **dst_fence,
|
||||
struct pipe_fence *src_fence );
|
||||
|
||||
int (*fence_is_signalled)( struct i915_winsys *sws,
|
||||
struct pipe_fence *fence );
|
||||
|
||||
int (*fence_wait)( struct i915_winsys *sws,
|
||||
struct pipe_fence *fence );
|
||||
|
||||
};
|
||||
|
||||
#define I915_BUFFER_ACCESS_WRITE 0x1
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ struct pipe_rasterizer_state
|
|||
unsigned line_stipple_enable:1;
|
||||
unsigned line_stipple_factor:8; /**< [1..256] actually */
|
||||
unsigned line_stipple_pattern:16;
|
||||
unsigned bypass_clipping:1;
|
||||
|
||||
float line_width;
|
||||
float point_size; /**< used when no per-vertex size */
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ DRIVER_SOURCES = \
|
|||
sp_quad_colormask.c \
|
||||
sp_quad_coverage.c \
|
||||
sp_quad_depth_test.c \
|
||||
sp_quad_earlyz.c \
|
||||
sp_quad_fs.c \
|
||||
sp_quad_occlusion.c \
|
||||
sp_quad_output.c \
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ static void softpipe_destroy( struct pipe_context *pipe )
|
|||
draw_destroy( softpipe->draw );
|
||||
|
||||
softpipe->quad.polygon_stipple->destroy( softpipe->quad.polygon_stipple );
|
||||
softpipe->quad.earlyz->destroy( softpipe->quad.earlyz );
|
||||
softpipe->quad.shade->destroy( softpipe->quad.shade );
|
||||
softpipe->quad.alpha_test->destroy( softpipe->quad.alpha_test );
|
||||
softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
|
||||
|
|
@ -369,6 +370,7 @@ struct pipe_context *softpipe_create( struct pipe_winsys *pipe_winsys,
|
|||
|
||||
/* setup quad rendering stages */
|
||||
softpipe->quad.polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
|
||||
softpipe->quad.earlyz = sp_quad_earlyz_stage(softpipe);
|
||||
softpipe->quad.shade = sp_quad_shade_stage(softpipe);
|
||||
softpipe->quad.alpha_test = sp_quad_alpha_test_stage(softpipe);
|
||||
softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ struct softpipe_context {
|
|||
/** 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;
|
||||
|
|
|
|||
|
|
@ -28,24 +28,52 @@
|
|||
|
||||
#include "sp_context.h"
|
||||
|
||||
#include "sp_state.h"
|
||||
#include "pipe/tgsi/exec/tgsi_token.h"
|
||||
|
||||
static void
|
||||
sp_push_quad_first(
|
||||
struct softpipe_context *sp,
|
||||
struct quad_stage *quad )
|
||||
{
|
||||
quad->next = sp->quad.first;
|
||||
sp->quad.first = quad;
|
||||
}
|
||||
|
||||
static void
|
||||
sp_build_depth_stencil(
|
||||
struct softpipe_context *sp )
|
||||
{
|
||||
if (sp->depth_stencil->stencil.front_enabled ||
|
||||
sp->depth_stencil->stencil.back_enabled) {
|
||||
sp_push_quad_first( sp, sp->quad.stencil_test );
|
||||
}
|
||||
else if (sp->depth_stencil->depth.enabled &&
|
||||
sp->framebuffer.zbuf) {
|
||||
sp_push_quad_first( sp, sp->quad.depth_test );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sp_build_quad_pipeline(struct softpipe_context *sp)
|
||||
{
|
||||
boolean early_depth_test =
|
||||
sp->depth_stencil->depth.enabled &&
|
||||
sp->framebuffer.zbuf &&
|
||||
!sp->alpha_test->enabled &&
|
||||
sp->fs->shader.output_semantic_name[0] != TGSI_SEMANTIC_POSITION;
|
||||
|
||||
/* build up the pipeline in reverse order... */
|
||||
|
||||
sp->quad.first = sp->quad.output;
|
||||
|
||||
if (sp->blend->colormask != 0xf) {
|
||||
sp->quad.colormask->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.colormask;
|
||||
sp_push_quad_first( sp, sp->quad.colormask );
|
||||
}
|
||||
|
||||
if (sp->blend->blend_enable ||
|
||||
sp->blend->logicop_enable) {
|
||||
sp->quad.blend->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.blend;
|
||||
sp_push_quad_first( sp, sp->quad.blend );
|
||||
}
|
||||
|
||||
if (sp->framebuffer.num_cbufs == 1) {
|
||||
|
|
@ -54,46 +82,38 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
|
|||
}
|
||||
else {
|
||||
/* insert bufloop stage */
|
||||
sp->quad.bufloop->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.bufloop;
|
||||
sp_push_quad_first( sp, sp->quad.bufloop );
|
||||
}
|
||||
|
||||
if (sp->depth_stencil->depth.occlusion_count) {
|
||||
sp->quad.occlusion->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.occlusion;
|
||||
sp_push_quad_first( sp, sp->quad.occlusion );
|
||||
}
|
||||
|
||||
if (sp->rasterizer->poly_smooth ||
|
||||
sp->rasterizer->line_smooth ||
|
||||
sp->rasterizer->point_smooth) {
|
||||
sp->quad.coverage->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.coverage;
|
||||
sp_push_quad_first( sp, sp->quad.coverage );
|
||||
}
|
||||
|
||||
if ( sp->depth_stencil->stencil.front_enabled
|
||||
|| sp->depth_stencil->stencil.back_enabled) {
|
||||
sp->quad.stencil_test->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.stencil_test;
|
||||
}
|
||||
else if (sp->depth_stencil->depth.enabled &&
|
||||
sp->framebuffer.zbuf) {
|
||||
sp->quad.depth_test->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.depth_test;
|
||||
if (!early_depth_test) {
|
||||
sp_build_depth_stencil( sp );
|
||||
}
|
||||
|
||||
if (sp->alpha_test->enabled) {
|
||||
sp->quad.alpha_test->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.alpha_test;
|
||||
sp_push_quad_first( sp, sp->quad.alpha_test );
|
||||
}
|
||||
|
||||
/* XXX always enable shader? */
|
||||
if (1) {
|
||||
sp->quad.shade->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.shade;
|
||||
sp_push_quad_first( sp, sp->quad.shade );
|
||||
}
|
||||
|
||||
if (early_depth_test) {
|
||||
sp_build_depth_stencil( sp );
|
||||
sp_push_quad_first( sp, sp->quad.earlyz );
|
||||
}
|
||||
|
||||
if (sp->rasterizer->poly_stipple_enable) {
|
||||
sp->quad.polygon_stipple->next = sp->quad.first;
|
||||
sp->quad.first = sp->quad.polygon_stipple;
|
||||
sp_push_quad_first( sp, sp->quad.polygon_stipple );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ struct quad_stage {
|
|||
|
||||
|
||||
struct quad_stage *sp_quad_polygon_stipple_stage( struct softpipe_context *softpipe );
|
||||
struct quad_stage *sp_quad_earlyz_stage( struct softpipe_context *softpipe );
|
||||
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe );
|
||||
struct quad_stage *sp_quad_alpha_test_stage( struct softpipe_context *softpipe );
|
||||
struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe );
|
||||
|
|
|
|||
|
|
@ -119,6 +119,21 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
{
|
||||
float scale = (float) ((1 << 24) - 1);
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
qzzzz[j] = (unsigned) (quad->outputs.depth[j] * scale);
|
||||
}
|
||||
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->y0 % TILE_SIZE + (j >> 1);
|
||||
bzzzz[j] = tile->data.depth32[y][x] >> 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -210,6 +225,15 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
tile->data.depth32[y][x] = s8z24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->y0 % TILE_SIZE + (j >> 1);
|
||||
uint z24s8 = tile->data.depth32[y][x];
|
||||
z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 24);
|
||||
tile->data.depth32[y][x] = z24s8;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
92
src/mesa/pipe/softpipe/sp_quad_earlyz.c
Normal file
92
src/mesa/pipe/softpipe/sp_quad_earlyz.c
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 "pipe/p_util.h"
|
||||
#include "sp_headers.h"
|
||||
#include "sp_quad.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->x0;
|
||||
const float fy = (float) quad->y0;
|
||||
const float dzdx = quad->coef[0].dadx[2];
|
||||
const float dzdy = quad->coef[0].dady[2];
|
||||
const float z0 = quad->coef[0].a0[2] + dzdx * fx + dzdy * fy;
|
||||
|
||||
quad->outputs.depth[0] = z0;
|
||||
quad->outputs.depth[1] = z0 + dzdx;
|
||||
quad->outputs.depth[2] = z0 + dzdy;
|
||||
quad->outputs.depth[3] = z0 + dzdx + dzdy;
|
||||
|
||||
if (qs->next) {
|
||||
qs->next->run( qs->next, quad );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
earlyz_begin(
|
||||
struct quad_stage *qs )
|
||||
{
|
||||
if (qs->next) {
|
||||
qs->next->begin( qs->next );
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
earlyz_destroy(
|
||||
struct quad_stage *qs )
|
||||
{
|
||||
FREE( qs );
|
||||
}
|
||||
|
||||
struct quad_stage *
|
||||
sp_quad_earlyz_stage(
|
||||
struct softpipe_context *softpipe )
|
||||
{
|
||||
struct quad_stage *stage = CALLOC_STRUCT( quad_stage );
|
||||
|
||||
stage->softpipe = softpipe;
|
||||
stage->begin = earlyz_begin;
|
||||
stage->run = earlyz_quad;
|
||||
stage->destroy = earlyz_destroy;
|
||||
|
||||
return stage;
|
||||
}
|
||||
|
|
@ -104,6 +104,10 @@ shade_quad(
|
|||
machine->Inputs[0].xyzw[0].f[2] = fx;
|
||||
machine->Inputs[0].xyzw[0].f[3] = fx + 1.0f;
|
||||
|
||||
/* XXX for OpenGL we need to invert the Y pos here (y=0=top).
|
||||
* but that'll mess up linear/perspective interpolation of other
|
||||
* attributes...
|
||||
*/
|
||||
machine->Inputs[0].xyzw[1].f[0] = fy;
|
||||
machine->Inputs[0].xyzw[1].f[1] = fy;
|
||||
machine->Inputs[0].xyzw[1].f[2] = fy + 1.0f;
|
||||
|
|
|
|||
|
|
@ -241,6 +241,13 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
stencilVals[j] = tile->data.depth32[y][x] >> 24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->y0 % TILE_SIZE + (j >> 1);
|
||||
stencilVals[j] = tile->data.depth32[y][x] & 0xff;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_U_S8:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
|
|
@ -300,6 +307,15 @@ stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
|
|||
tile->data.depth32[y][x] = s8z24;
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
int y = quad->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_U_S8:
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
int x = quad->x0 % TILE_SIZE + (j & 1);
|
||||
|
|
|
|||
|
|
@ -461,6 +461,40 @@ s8z24_get_tile(struct pipe_surface *ps,
|
|||
}
|
||||
|
||||
|
||||
/*** PIPE_FORMAT_Z24_S8 ***/
|
||||
|
||||
/**
|
||||
* Return Z component as four float in [0,1]. Stencil part ignored.
|
||||
*/
|
||||
static void
|
||||
z24s8_get_tile(struct pipe_surface *ps,
|
||||
unsigned x, unsigned y, unsigned w, unsigned h, float *p)
|
||||
{
|
||||
const uint *src
|
||||
= ((const uint *) (ps->region->map + ps->offset))
|
||||
+ y * ps->region->pitch + x;
|
||||
const double scale = 1.0 / ((1 << 24) - 1);
|
||||
unsigned i, j;
|
||||
unsigned w0 = w;
|
||||
|
||||
assert(ps->format == PIPE_FORMAT_Z24_S8);
|
||||
|
||||
CLIP_TILE;
|
||||
|
||||
for (i = 0; i < h; i++) {
|
||||
float *pRow = p;
|
||||
for (j = 0; j < w; j++) {
|
||||
pRow[j * 4 + 0] =
|
||||
pRow[j * 4 + 1] =
|
||||
pRow[j * 4 + 2] =
|
||||
pRow[j * 4 + 3] = (float) (scale * (src[j] >> 8));
|
||||
}
|
||||
src += ps->region->pitch;
|
||||
p += 4 * w0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via pipe->get_tex_surface()
|
||||
* XXX is this in the right place?
|
||||
|
|
@ -601,6 +635,9 @@ softpipe_get_tile_rgba(struct pipe_context *pipe,
|
|||
case PIPE_FORMAT_S8_Z24:
|
||||
s8z24_get_tile(ps, x, y, w, h, p);
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
z24s8_get_tile(ps, x, y, w, h, p);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
@ -645,6 +682,9 @@ softpipe_put_tile_rgba(struct pipe_context *pipe,
|
|||
case PIPE_FORMAT_S8_Z24:
|
||||
/*s8z24_put_tile(ps, x, y, w, h, p);*/
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
/*z24s8_put_tile(ps, x, y, w, h, p);*/
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
|
|||
return;
|
||||
|
||||
is_depth_stencil = (ps->format == PIPE_FORMAT_S8_Z24 ||
|
||||
ps->format == PIPE_FORMAT_Z24_S8 ||
|
||||
ps->format == PIPE_FORMAT_U_Z16 ||
|
||||
ps->format == PIPE_FORMAT_U_Z32 ||
|
||||
ps->format == PIPE_FORMAT_U_S8);
|
||||
|
|
@ -203,6 +204,7 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
|
|||
struct pipe_surface *ps = tc->surface;
|
||||
boolean is_depth_stencil
|
||||
= (ps->format == PIPE_FORMAT_S8_Z24 ||
|
||||
ps->format == PIPE_FORMAT_Z24_S8 ||
|
||||
ps->format == PIPE_FORMAT_U_Z16 ||
|
||||
ps->format == PIPE_FORMAT_U_Z32 ||
|
||||
ps->format == PIPE_FORMAT_U_S8);
|
||||
|
|
@ -268,6 +270,17 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
|
|||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_Z24_S8:
|
||||
{
|
||||
uint clear_val = ((uint) (tc->clear_value[0] * 0xffffff)) << 8;
|
||||
clear_val |= ((uint) tc->clear_value[1]) & 0xff;
|
||||
for (i = 0; i < TILE_SIZE; i++) {
|
||||
for (j = 0; j < TILE_SIZE; j++) {
|
||||
tile->data.depth32[i][j] = clear_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_U_S8:
|
||||
{
|
||||
ubyte clear_val = (uint) tc->clear_value[0];
|
||||
|
|
|
|||
|
|
@ -1346,17 +1346,15 @@ linear_interpolation(
|
|||
unsigned attrib,
|
||||
unsigned chan )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for( i = 0; i < QUAD_SIZE; i++ ) {
|
||||
const float x = mach->Inputs[0].xyzw[0].f[i];
|
||||
const float y = mach->Inputs[0].xyzw[1].f[i];
|
||||
|
||||
mach->Inputs[attrib].xyzw[chan].f[i] =
|
||||
mach->InterpCoefs[attrib].a0[chan] +
|
||||
mach->InterpCoefs[attrib].dadx[chan] * x +
|
||||
mach->InterpCoefs[attrib].dady[chan] * y;
|
||||
}
|
||||
const float x = mach->Inputs[0].xyzw[0].f[0];
|
||||
const float y = mach->Inputs[0].xyzw[1].f[0];
|
||||
const float dadx = mach->InterpCoefs[attrib].dadx[chan];
|
||||
const float dady = mach->InterpCoefs[attrib].dady[chan];
|
||||
const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
|
||||
mach->Inputs[attrib].xyzw[chan].f[0] = a0;
|
||||
mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx;
|
||||
mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady;
|
||||
mach->Inputs[attrib].xyzw[chan].f[3] = a0 + dadx + dady;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1365,20 +1363,15 @@ perspective_interpolation(
|
|||
unsigned attrib,
|
||||
unsigned chan )
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for( i = 0; i < QUAD_SIZE; i++ ) {
|
||||
const float x = mach->Inputs[0].xyzw[0].f[i];
|
||||
const float y = mach->Inputs[0].xyzw[1].f[i];
|
||||
/* WPOS.w here is really 1/w */
|
||||
const float w = 1.0f / mach->Inputs[0].xyzw[3].f[i];
|
||||
assert(mach->Inputs[0].xyzw[3].f[i] != 0.0);
|
||||
|
||||
mach->Inputs[attrib].xyzw[chan].f[i] =
|
||||
(mach->InterpCoefs[attrib].a0[chan] +
|
||||
mach->InterpCoefs[attrib].dadx[chan] * x +
|
||||
mach->InterpCoefs[attrib].dady[chan] * y) * w;
|
||||
}
|
||||
const float x = mach->Inputs[0].xyzw[0].f[0];
|
||||
const float y = mach->Inputs[0].xyzw[1].f[0];
|
||||
const float dadx = mach->InterpCoefs[attrib].dadx[chan];
|
||||
const float dady = mach->InterpCoefs[attrib].dady[chan];
|
||||
const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
|
||||
mach->Inputs[attrib].xyzw[chan].f[0] = a0 / mach->Inputs[0].xyzw[3].f[0];
|
||||
mach->Inputs[attrib].xyzw[chan].f[1] = (a0 + dadx) / mach->Inputs[0].xyzw[3].f[1];
|
||||
mach->Inputs[attrib].xyzw[chan].f[2] = (a0 + dady) / mach->Inputs[0].xyzw[3].f[2];
|
||||
mach->Inputs[attrib].xyzw[chan].f[3] = (a0 + dadx + dady) / mach->Inputs[0].xyzw[3].f[3];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -25,353 +25,229 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Brian Paul
|
||||
*/
|
||||
/**
|
||||
* glRasterPos implementation. Basically render a GL_POINT with our
|
||||
* private draw module. Plug in a special "rasterpos" stage at the end
|
||||
* of the 'draw' pipeline to capture the results and update the current
|
||||
* raster pos attributes.
|
||||
*
|
||||
* Authors:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/feedback.h"
|
||||
#include "main/macros.h"
|
||||
|
||||
#include "st_context.h"
|
||||
#include "st_atom.h"
|
||||
#include "st_cache.h"
|
||||
#include "st_draw.h"
|
||||
#include "st_program.h"
|
||||
#include "st_cb_rasterpos.h"
|
||||
#include "st_draw.h"
|
||||
#include "st_format.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/draw/draw_context.h"
|
||||
#include "pipe/draw/draw_private.h"
|
||||
#include "shader/prog_instruction.h"
|
||||
#include "vbo/vbo.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Our special drawing pipeline stage (replaces rasterization).
|
||||
*/
|
||||
struct rastpos_stage
|
||||
{
|
||||
struct draw_stage stage; /**< Base class */
|
||||
GLcontext *ctx; /**< Rendering context */
|
||||
|
||||
/* vertex attrib info we can setup once and re-use */
|
||||
struct gl_client_array array[VERT_ATTRIB_MAX];
|
||||
const struct gl_client_array *arrays[VERT_ATTRIB_MAX];
|
||||
struct _mesa_prim prim;
|
||||
};
|
||||
|
||||
|
||||
static INLINE struct rastpos_stage *
|
||||
rastpos_stage( struct draw_stage *stage )
|
||||
{
|
||||
return (struct rastpos_stage *) stage;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_vertex_attribs(GLcontext *ctx)
|
||||
rastpos_begin( struct draw_stage *stage )
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
const struct cso_vertex_shader *vs = ctx->st->state.vs;
|
||||
const struct st_vertex_program *stvp = ctx->st->vp;
|
||||
uint slot;
|
||||
|
||||
/* all attributes come from the default attribute buffer */
|
||||
{
|
||||
struct pipe_vertex_buffer vbuffer;
|
||||
vbuffer.buffer = ctx->st->default_attrib_buffer;
|
||||
vbuffer.buffer_offset = 0;
|
||||
vbuffer.pitch = 0; /* must be zero! */
|
||||
vbuffer.max_index = 1;
|
||||
pipe->set_vertex_buffer(pipe, 0, &vbuffer);
|
||||
}
|
||||
|
||||
for (slot = 0; slot < vs->state.num_inputs; slot++) {
|
||||
struct pipe_vertex_element velement;
|
||||
const GLuint attr = stvp->index_to_input[slot];
|
||||
|
||||
velement.src_offset = attr * 4 * sizeof(GLfloat);
|
||||
velement.vertex_buffer_index = 0;
|
||||
velement.dst_offset = 0;
|
||||
velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
pipe->set_vertex_element(pipe, slot, &velement);
|
||||
}
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
setup_feedback(GLcontext *ctx)
|
||||
rastpos_end( struct draw_stage *stage )
|
||||
{
|
||||
struct pipe_context *pipe = ctx->st->pipe;
|
||||
const struct pipe_shader_state *vs = &ctx->st->state.vs->state;
|
||||
struct pipe_feedback_state feedback;
|
||||
uint i;
|
||||
|
||||
memset(&feedback, 0, sizeof(feedback));
|
||||
feedback.enabled = 1;
|
||||
feedback.interleaved = 1;
|
||||
feedback.discard = 1;
|
||||
feedback.num_attribs = 0;
|
||||
|
||||
/* feedback all results from vertex shader */
|
||||
for (i = 0; i < vs->num_outputs; i++) {
|
||||
feedback.attrib[feedback.num_attribs] = i;
|
||||
feedback.size[feedback.num_attribs] = 4;
|
||||
feedback.num_attribs++;
|
||||
}
|
||||
|
||||
if (pipe->set_feedback_state)
|
||||
pipe->set_feedback_state(pipe, &feedback);
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clip a point against the view volume.
|
||||
*
|
||||
* \param v vertex vector describing the point to clip.
|
||||
*
|
||||
* \return zero if outside view volume, or one if inside.
|
||||
*/
|
||||
static GLuint
|
||||
viewclip_point( const GLfloat v[] )
|
||||
static void
|
||||
rastpos_reset_stipple_counter( struct draw_stage *stage )
|
||||
{
|
||||
if ( v[0] > v[3] || v[0] < -v[3]
|
||||
|| v[1] > v[3] || v[1] < -v[3]
|
||||
|| v[2] > v[3] || v[2] < -v[3] ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
static void
|
||||
rastpos_tri( struct draw_stage *stage, struct prim_header *prim )
|
||||
{
|
||||
/* should never get here */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
static void
|
||||
rastpos_line( struct draw_stage *stage, struct prim_header *prim )
|
||||
{
|
||||
/* should never get here */
|
||||
assert(0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip a point against the far/near Z clipping planes.
|
||||
*
|
||||
* \param v vertex vector describing the point to clip.
|
||||
*
|
||||
* \return zero if outside view volume, or one if inside.
|
||||
*/
|
||||
static GLuint
|
||||
viewclip_point_z( const GLfloat v[] )
|
||||
{
|
||||
if (v[2] > v[3] || v[2] < -v[3] ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clip a point against the user clipping planes.
|
||||
*
|
||||
* \param ctx GL context.
|
||||
* \param v vertex vector describing the point to clip.
|
||||
*
|
||||
* \return zero if the point was clipped, or one otherwise.
|
||||
*/
|
||||
static GLuint
|
||||
userclip_point( GLcontext *ctx, const GLfloat v[] )
|
||||
{
|
||||
GLuint p;
|
||||
|
||||
for (p = 0; p < ctx->Const.MaxClipPlanes; p++) {
|
||||
if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {
|
||||
GLfloat dot = v[0] * ctx->Transform._ClipUserPlane[p][0]
|
||||
+ v[1] * ctx->Transform._ClipUserPlane[p][1]
|
||||
+ v[2] * ctx->Transform._ClipUserPlane[p][2]
|
||||
+ v[3] * ctx->Transform._ClipUserPlane[p][3];
|
||||
if (dot < 0.0F) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the current raster position.
|
||||
* Do clip testing, etc. here.
|
||||
* Update a raster pos attribute from the vertex result if it's present,
|
||||
* else copy the current attrib.
|
||||
*/
|
||||
static void
|
||||
update_rasterpos(GLcontext *ctx,
|
||||
const float clipPos[4],
|
||||
const float color0[4],
|
||||
const float color1[4],
|
||||
const float *fog,
|
||||
const float *tex)
|
||||
update_attrib(GLcontext *ctx, const GLuint *outputMapping,
|
||||
const struct vertex_header *vert,
|
||||
GLfloat *dest,
|
||||
GLuint result, GLuint defaultAttrib)
|
||||
{
|
||||
uint i;
|
||||
float d, ndc[3];
|
||||
|
||||
/* clip to view volume */
|
||||
if (ctx->Transform.RasterPositionUnclipped) {
|
||||
/* GL_IBM_rasterpos_clip: only clip against Z */
|
||||
if (viewclip_point_z(clipPos) == 0) {
|
||||
ctx->Current.RasterPosValid = GL_FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (viewclip_point(clipPos) == 0) {
|
||||
/* Normal OpenGL behaviour */
|
||||
ctx->Current.RasterPosValid = GL_FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* clip to user clipping planes */
|
||||
if (ctx->Transform.ClipPlanesEnabled && !userclip_point(ctx, clipPos)) {
|
||||
ctx->Current.RasterPosValid = GL_FALSE;
|
||||
return;
|
||||
}
|
||||
const GLfloat *src;
|
||||
const GLuint k = outputMapping[result];
|
||||
if (k != ~0)
|
||||
src = vert->data[k];
|
||||
else
|
||||
src = ctx->Current.Attrib[defaultAttrib];
|
||||
COPY_4V(dest, src);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* update current raster position
|
||||
*/
|
||||
/* ndc = clip / W */
|
||||
d = (clipPos[3] == 0.0F) ? 1.0F : 1.0F / clipPos[3];
|
||||
ndc[0] = clipPos[0] * d;
|
||||
ndc[1] = clipPos[1] * d;
|
||||
ndc[2] = clipPos[2] * d;
|
||||
/* wincoord = viewport_mapping(ndc) */
|
||||
ctx->Current.RasterPos[0] = (ndc[0] * ctx->Viewport._WindowMap.m[MAT_SX]
|
||||
+ ctx->Viewport._WindowMap.m[MAT_TX]);
|
||||
ctx->Current.RasterPos[1] = (ndc[1] * ctx->Viewport._WindowMap.m[MAT_SY]
|
||||
+ ctx->Viewport._WindowMap.m[MAT_TY]);
|
||||
ctx->Current.RasterPos[2] = (ndc[2] * ctx->Viewport._WindowMap.m[MAT_SZ]
|
||||
+ ctx->Viewport._WindowMap.m[MAT_TZ])
|
||||
/ ctx->DrawBuffer->_DepthMaxF;
|
||||
ctx->Current.RasterPos[3] = clipPos[3];
|
||||
|
||||
/* compute raster distance */
|
||||
#if 0
|
||||
if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
|
||||
ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
|
||||
else {
|
||||
/* XXX we don't have an eye coord! */
|
||||
ctx->Current.RasterDistance =
|
||||
SQRTF( eye[0]*eye[0] + eye[1]*eye[1] + eye[2]*eye[2] );
|
||||
}
|
||||
#else
|
||||
ctx->Current.RasterDistance = fog[0];
|
||||
#endif
|
||||
|
||||
/* colors and texcoords */
|
||||
COPY_4FV(ctx->Current.RasterColor, color0);
|
||||
COPY_4FV(ctx->Current.RasterSecondaryColor, color1);
|
||||
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
|
||||
COPY_4FV(ctx->Current.RasterTexCoords + i, tex + i *4);
|
||||
}
|
||||
/**
|
||||
* Normally, this function would render a GL_POINT.
|
||||
*/
|
||||
static void
|
||||
rastpos_point(struct draw_stage *stage, struct prim_header *prim)
|
||||
{
|
||||
struct rastpos_stage *rs = rastpos_stage(stage);
|
||||
GLcontext *ctx = rs->ctx;
|
||||
struct st_context *st = ctx->st;
|
||||
const GLfloat height = ctx->DrawBuffer->Height;
|
||||
const GLuint *outputMapping = st->vertex_result_to_slot;
|
||||
const GLfloat *pos;
|
||||
GLuint i;
|
||||
|
||||
/* if we get here, we didn't get clipped */
|
||||
ctx->Current.RasterPosValid = GL_TRUE;
|
||||
|
||||
if (ctx->RenderMode == GL_SELECT) {
|
||||
_mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
|
||||
/* update raster pos */
|
||||
pos = prim->v[0]->data[0];
|
||||
ctx->Current.RasterPos[0] = pos[0];
|
||||
ctx->Current.RasterPos[1] = height - 1 - pos[1];
|
||||
ctx->Current.RasterPos[2] = pos[2];
|
||||
ctx->Current.RasterPos[3] = pos[3];
|
||||
|
||||
/* update other raster attribs */
|
||||
update_attrib(ctx, outputMapping, prim->v[0],
|
||||
ctx->Current.RasterColor,
|
||||
VERT_RESULT_COL0, VERT_ATTRIB_COLOR0);
|
||||
|
||||
update_attrib(ctx, outputMapping, prim->v[0],
|
||||
ctx->Current.RasterSecondaryColor,
|
||||
VERT_RESULT_COL1, VERT_ATTRIB_COLOR1);
|
||||
|
||||
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
|
||||
update_attrib(ctx, outputMapping, prim->v[0],
|
||||
ctx->Current.RasterTexCoords[i],
|
||||
VERT_RESULT_TEX0 + i, VERT_ATTRIB_TEX0 + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create rasterpos "drawing" stage.
|
||||
*/
|
||||
static struct rastpos_stage *
|
||||
new_draw_rastpos_stage(GLcontext *ctx, struct draw_context *draw)
|
||||
{
|
||||
struct rastpos_stage *rs = CALLOC_STRUCT(rastpos_stage);
|
||||
|
||||
rs->stage.draw = draw;
|
||||
rs->stage.next = NULL;
|
||||
rs->stage.begin = rastpos_begin;
|
||||
rs->stage.point = rastpos_point;
|
||||
rs->stage.line = rastpos_line;
|
||||
rs->stage.tri = rastpos_tri;
|
||||
rs->stage.end = rastpos_end;
|
||||
rs->stage.reset_stipple_counter = rastpos_reset_stipple_counter;
|
||||
rs->ctx = ctx;
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_RasterPos(GLcontext *ctx, const GLfloat v[4])
|
||||
{
|
||||
const struct st_context *st = ctx->st;
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
float *buf_map;
|
||||
struct pipe_feedback_buffer fb_buf;
|
||||
struct st_context *st = ctx->st;
|
||||
struct draw_context *draw = st->draw;
|
||||
struct rastpos_stage *rs;
|
||||
|
||||
if (st->rastpos_stage) {
|
||||
/* get rastpos stage info */
|
||||
rs = rastpos_stage(st->rastpos_stage);
|
||||
}
|
||||
else {
|
||||
/* create rastpos draw stage */
|
||||
GLuint i;
|
||||
|
||||
rs = new_draw_rastpos_stage(ctx, draw);
|
||||
st->rastpos_stage = &rs->stage;
|
||||
|
||||
/* one-time init */
|
||||
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
|
||||
rs->array[i].Size = 4;
|
||||
rs->array[i].Type = GL_FLOAT;
|
||||
rs->array[i].Stride = 0;
|
||||
rs->array[i].StrideB = 0;
|
||||
rs->array[i].Ptr = (GLubyte *) ctx->Current.Attrib[i];
|
||||
rs->array[i].Enabled = GL_TRUE;
|
||||
rs->array[i].Normalized = GL_TRUE;
|
||||
rs->array[i].BufferObj = NULL;
|
||||
rs->arrays[i] = &rs->array[i];
|
||||
}
|
||||
|
||||
rs->prim.mode = GL_POINTS;
|
||||
rs->prim.indexed = 0;
|
||||
rs->prim.begin = 1;
|
||||
rs->prim.end = 1;
|
||||
rs->prim.weak = 0;
|
||||
rs->prim.start = 0;
|
||||
rs->prim.count = 1;
|
||||
}
|
||||
|
||||
/* plug our rastpos stage into the draw module */
|
||||
draw_set_rasterize_stage(st->draw, st->rastpos_stage);
|
||||
|
||||
/* make sure everything's up to date */
|
||||
st_validate_state(ctx->st);
|
||||
|
||||
/* setup vertex buffers */
|
||||
setup_vertex_attribs(ctx);
|
||||
/* This will get set only if rastpos_point(), above, gets called */
|
||||
ctx->Current.RasterPosValid = GL_FALSE;
|
||||
|
||||
/*
|
||||
* Load the default attribute buffer with current attribs.
|
||||
/* All vertex attribs but position were previously initialized above.
|
||||
* Just plug in position pointer now.
|
||||
*/
|
||||
{
|
||||
struct pipe_buffer_handle *buf = st->default_attrib_buffer;
|
||||
const unsigned size = sizeof(ctx->Current.Attrib);
|
||||
const void *data = ctx->Current.Attrib;
|
||||
/* colors, texcoords, etc */
|
||||
pipe->winsys->buffer_data(pipe->winsys, buf,
|
||||
size, data,
|
||||
PIPE_BUFFER_USAGE_VERTEX);
|
||||
/* position */
|
||||
pipe->winsys->buffer_subdata(pipe->winsys, buf,
|
||||
0, /* offset */
|
||||
4 * sizeof(float), /* size */
|
||||
v); /* data */
|
||||
}
|
||||
rs->array[0].Ptr = (GLubyte *) v;
|
||||
|
||||
|
||||
/* setup feedback state */
|
||||
setup_feedback(ctx);
|
||||
|
||||
/* setup vertex feedback buffer */
|
||||
{
|
||||
fb_buf.size = 8 * 4 * sizeof(float);
|
||||
fb_buf.buffer = pipe->winsys->buffer_create(pipe->winsys, 0);
|
||||
fb_buf.start_offset = 0;
|
||||
pipe->winsys->buffer_data(pipe->winsys, fb_buf.buffer,
|
||||
fb_buf.size,
|
||||
NULL, /* data */
|
||||
PIPE_BUFFER_USAGE_VERTEX);
|
||||
if (pipe->set_feedback_buffer)
|
||||
pipe->set_feedback_buffer(pipe, 0, &fb_buf);
|
||||
}
|
||||
|
||||
|
||||
/* draw a point */
|
||||
pipe->draw_arrays(pipe, GL_POINTS, 0, 1);
|
||||
|
||||
/* get feedback */
|
||||
buf_map = (float *) pipe->winsys->buffer_map(pipe->winsys, fb_buf.buffer,
|
||||
PIPE_BUFFER_FLAG_READ);
|
||||
|
||||
/* extract values and update rasterpos state */
|
||||
{
|
||||
const GLuint *outputMapping = st->vertex_result_to_slot;
|
||||
const float *pos, *color0, *color1, *fog, *tex0;
|
||||
float *buf = buf_map;
|
||||
|
||||
assert(outputMapping[VERT_RESULT_HPOS] != ~0);
|
||||
pos = buf;
|
||||
buf += 4;
|
||||
|
||||
if (outputMapping[VERT_RESULT_COL0] != ~0) {
|
||||
color0 = buf;
|
||||
buf += 4;
|
||||
}
|
||||
else {
|
||||
color0 = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
|
||||
}
|
||||
|
||||
if (outputMapping[VERT_RESULT_COL1] != ~0) {
|
||||
color1 = buf;
|
||||
buf += 4;
|
||||
}
|
||||
else {
|
||||
color1 = ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
|
||||
}
|
||||
|
||||
if (outputMapping[VERT_RESULT_FOGC] != ~0) {
|
||||
fog = buf;
|
||||
buf += 4;
|
||||
}
|
||||
else {
|
||||
fog = ctx->Current.Attrib[VERT_ATTRIB_FOG];
|
||||
}
|
||||
|
||||
if (outputMapping[VERT_RESULT_TEX0] != ~0) {
|
||||
tex0 = buf;
|
||||
buf += 4;
|
||||
}
|
||||
else {
|
||||
tex0 = ctx->Current.Attrib[VERT_ATTRIB_TEX0];
|
||||
}
|
||||
|
||||
update_rasterpos(ctx, pos, color0, color1, fog, tex0);
|
||||
}
|
||||
|
||||
/* free vertex feedback buffer */
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, fb_buf.buffer);
|
||||
pipe->winsys->buffer_reference(pipe->winsys, &fb_buf.buffer, NULL);
|
||||
|
||||
/* restore pipe state */
|
||||
if (pipe->set_feedback_state)
|
||||
pipe->set_feedback_state(pipe, &st->state.feedback);
|
||||
/* draw the point */
|
||||
st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void st_init_rasterpos_functions(struct dd_function_table *functions)
|
||||
{
|
||||
functions->RasterPos = st_RasterPos;
|
||||
|
|
|
|||
|
|
@ -68,9 +68,10 @@ struct st_context
|
|||
|
||||
struct pipe_context *pipe;
|
||||
|
||||
struct draw_context *draw; /**< For selection/feedback */
|
||||
struct draw_context *draw; /**< For selection/feedback/rastpos only */
|
||||
struct draw_stage *feedback_stage; /**< For GL_FEEDBACK rendermode */
|
||||
struct draw_stage *selection_stage; /**< For GL_SELECT rendermode */
|
||||
struct draw_stage *rastpos_stage; /**< For glRasterPos */
|
||||
|
||||
/* Some state is contained in constant objects.
|
||||
* Other state is just parameter values.
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ st_draw_vertices(GLcontext *ctx, unsigned prim,
|
|||
|
||||
/**
|
||||
* Set the (private) draw module's post-transformed vertex format when in
|
||||
* GL_SELECT or GL_FEEDBACK mode.
|
||||
* GL_SELECT or GL_FEEDBACK mode or for glRasterPos.
|
||||
*/
|
||||
static void
|
||||
set_feedback_vertex_format(GLcontext *ctx)
|
||||
|
|
@ -328,7 +328,14 @@ set_feedback_vertex_format(GLcontext *ctx)
|
|||
enum interp_mode interp[PIPE_MAX_SHADER_OUTPUTS];
|
||||
GLuint n, i;
|
||||
|
||||
if (ctx->RenderMode == GL_FEEDBACK) {
|
||||
if (ctx->RenderMode == GL_SELECT) {
|
||||
assert(ctx->RenderMode == GL_SELECT);
|
||||
n = 1;
|
||||
attrs[0] = FORMAT_4F;
|
||||
interp[0] = INTERP_NONE;
|
||||
}
|
||||
else {
|
||||
/* GL_FEEDBACK, or glRasterPos */
|
||||
/* emit all attribs (pos, color, texcoord) as GLfloat[4] */
|
||||
n = st->state.vs->state.num_outputs;
|
||||
for (i = 0; i < n; i++) {
|
||||
|
|
@ -336,19 +343,14 @@ set_feedback_vertex_format(GLcontext *ctx)
|
|||
interp[i] = INTERP_NONE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
assert(ctx->RenderMode == GL_SELECT);
|
||||
n = 1;
|
||||
attrs[0] = FORMAT_4F;
|
||||
interp[0] = INTERP_NONE;
|
||||
}
|
||||
|
||||
draw_set_vertex_attributes(st->draw, attrs, interp, n);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by VBO to draw arrays when in selection or feedback mode.
|
||||
* Called by VBO to draw arrays when in selection or feedback mode and
|
||||
* to implement glRasterPos.
|
||||
* This is very much like the normal draw_vbo() function above.
|
||||
* Look at code refactoring some day.
|
||||
* Might move this into the failover module some day.
|
||||
|
|
@ -373,8 +375,6 @@ st_feedback_draw_vbo(GLcontext *ctx,
|
|||
GLuint attr, i;
|
||||
ubyte *mapped_constants;
|
||||
|
||||
assert(ctx->RenderMode == GL_SELECT ||
|
||||
ctx->RenderMode == GL_FEEDBACK);
|
||||
assert(draw);
|
||||
|
||||
st_validate_state(ctx->st);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue