gallium: add geometry shader support to gallium

This commit is contained in:
Zack Rusin 2009-12-14 17:11:46 -05:00
parent 57cce7a409
commit 89d8577fb3
54 changed files with 1159 additions and 137 deletions

View file

@ -42,6 +42,7 @@
#include "cso_cache/cso_context.h"
#include "cso_cache/cso_cache.h"
#include "cso_cache/cso_hash.h"
#include "cso_context.h"
struct cso_context {
struct pipe_context *pipe;
@ -85,8 +86,8 @@ struct cso_context {
void *blend, *blend_saved;
void *depth_stencil, *depth_stencil_saved;
void *rasterizer, *rasterizer_saved;
void *fragment_shader, *fragment_shader_saved;
void *vertex_shader, *vertex_shader_saved;
void *fragment_shader, *fragment_shader_saved, *geometry_shader;
void *vertex_shader, *vertex_shader_saved, *geometry_shader_saved;
struct pipe_framebuffer_state fb, fb_saved;
struct pipe_viewport_state vp, vp_saved;
@ -1027,3 +1028,38 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx,
}
return PIPE_OK;
}
enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
void *handle)
{
if (ctx->geometry_shader != handle) {
ctx->geometry_shader = handle;
ctx->pipe->bind_gs_state(ctx->pipe, handle);
}
return PIPE_OK;
}
void cso_delete_geometry_shader(struct cso_context *ctx, void *handle)
{
if (handle == ctx->geometry_shader) {
/* unbind before deleting */
ctx->pipe->bind_gs_state(ctx->pipe, NULL);
ctx->geometry_shader = NULL;
}
ctx->pipe->delete_gs_state(ctx->pipe, handle);
}
void cso_save_geometry_shader(struct cso_context *ctx)
{
assert(!ctx->geometry_shader_saved);
ctx->geometry_shader_saved = ctx->geometry_shader;
}
void cso_restore_geometry_shader(struct cso_context *ctx)
{
if (ctx->geometry_shader_saved != ctx->geometry_shader) {
ctx->pipe->bind_gs_state(ctx->pipe, ctx->geometry_shader_saved);
ctx->geometry_shader = ctx->geometry_shader_saved;
}
ctx->geometry_shader_saved = NULL;
}

View file

@ -146,6 +146,13 @@ void cso_save_vertex_shader(struct cso_context *cso);
void cso_restore_vertex_shader(struct cso_context *cso);
enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx,
void *handle);
void cso_delete_geometry_shader(struct cso_context *ctx, void *handle);
void cso_save_geometry_shader(struct cso_context *cso);
void cso_restore_geometry_shader(struct cso_context *cso);
enum pipe_error cso_set_framebuffer(struct cso_context *cso,
const struct pipe_framebuffer_state *fb);

View file

@ -5,6 +5,7 @@ LIBNAME = draw
C_SOURCES = \
draw_context.c \
draw_gs.c \
draw_pipe.c \
draw_pipe_aaline.c \
draw_pipe_aapoint.c \

View file

@ -40,7 +40,8 @@ draw = env.ConvenienceLibrary(
'draw_vs_llvm.c',
'draw_vs_ppc.c',
'draw_vs_sse.c',
'draw_vs_varient.c'
'draw_vs_varient.c',
'draw_gs.c'
])
auxiliaries.insert(0, draw)

View file

@ -36,6 +36,7 @@
#include "draw_context.h"
#include "draw_vbuf.h"
#include "draw_vs.h"
#include "draw_gs.h"
#include "draw_pt.h"
#include "draw_pipe.h"
@ -67,6 +68,9 @@ struct draw_context *draw_create( void )
if (!draw_vs_init( draw ))
goto fail;
if (!draw_gs_init( draw ))
goto fail;
return draw;
fail:
@ -231,11 +235,19 @@ draw_set_mapped_vertex_buffer(struct draw_context *draw,
void
draw_set_mapped_constant_buffer(struct draw_context *draw,
const void *buffer,
unsigned shader_type,
const void *buffer,
unsigned size )
{
draw->pt.user.constants = buffer;
draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
debug_assert(shader_type == PIPE_SHADER_VERTEX ||
shader_type == PIPE_SHADER_GEOMETRY);
if (shader_type == PIPE_SHADER_VERTEX) {
draw->pt.user.vs_constants = buffer;
draw_vs_set_constants( draw, (const float (*)[4])buffer, size );
} else if (shader_type == PIPE_SHADER_GEOMETRY) {
draw->pt.user.gs_constants = buffer;
draw_gs_set_constants( draw, (const float (*)[4])buffer, size );
}
}
@ -298,7 +310,7 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable )
* a post-transformed vertex.
*
* With this function, drivers that use the draw module should have no reason
* to track the current vertex shader.
* to track the current vertex/geometry shader.
*
* Note that the draw module may sometimes generate vertices with extra
* attributes (such as texcoords for AA lines). The driver can call this
@ -309,43 +321,59 @@ draw_set_force_passthrough( struct draw_context *draw, boolean enable )
* work for the drivers.
*/
int
draw_find_vs_output(const struct draw_context *draw,
uint semantic_name, uint semantic_index)
draw_find_shader_output(const struct draw_context *draw,
uint semantic_name, uint semantic_index)
{
const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
const struct draw_geometry_shader *gs = draw->gs.geometry_shader;
uint i;
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == semantic_name &&
vs->info.output_semantic_index[i] == semantic_index)
const struct tgsi_shader_info *info = &vs->info;
if (gs)
info = &gs->info;
for (i = 0; i < info->num_outputs; i++) {
if (info->output_semantic_name[i] == semantic_name &&
info->output_semantic_index[i] == semantic_index)
return i;
}
/* XXX there may be more than one extra vertex attrib.
* For example, simulated gl_FragCoord and gl_PointCoord.
*/
if (draw->extra_vp_outputs.semantic_name == semantic_name &&
draw->extra_vp_outputs.semantic_index == semantic_index) {
return draw->extra_vp_outputs.slot;
if (draw->extra_shader_outputs.semantic_name == semantic_name &&
draw->extra_shader_outputs.semantic_index == semantic_index) {
return draw->extra_shader_outputs.slot;
}
return 0;
}
/**
* Return number of vertex shader outputs.
* Return number of the shader outputs.
*
* If geometry shader is present, its output will be returned,
* if not vertex shader is used.
*/
uint
draw_num_vs_outputs(const struct draw_context *draw)
draw_num_shader_outputs(const struct draw_context *draw)
{
uint count = draw->vs.vertex_shader->info.num_outputs;
if (draw->extra_vp_outputs.slot > 0)
/* if geometry shader is present, its outputs go to te
* driver, not the vertex shaders */
if (draw->gs.geometry_shader)
count = draw->gs.geometry_shader->info.num_outputs;
if (draw->extra_shader_outputs.slot > 0)
count++;
return count;
}
/**
* Provide TGSI sampler objects for vertex shaders that use texture fetches.
* Provide TGSI sampler objects for vertex/geometry shaders that use texture fetches.
* This might only be used by software drivers for the time being.
*/
void
@ -355,6 +383,8 @@ draw_texture_samplers(struct draw_context *draw,
{
draw->vs.num_samplers = num_samplers;
draw->vs.samplers = samplers;
draw->gs.num_samplers = num_samplers;
draw->gs.samplers = samplers;
}
@ -421,3 +451,18 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
draw->flushing = FALSE;
}
}
int draw_current_shader_outputs(struct draw_context *draw)
{
if (draw->gs.geometry_shader)
return draw->gs.num_gs_outputs;
return draw->vs.num_vs_outputs;
}
int draw_current_shader_position_output(struct draw_context *draw)
{
if (draw->gs.geometry_shader)
return draw->gs.position_output;
return draw->vs.position_output;
}

View file

@ -45,6 +45,7 @@ struct pipe_context;
struct draw_context;
struct draw_stage;
struct draw_vertex_shader;
struct draw_geometry_shader;
struct tgsi_sampler;
@ -85,11 +86,11 @@ draw_install_pstipple_stage(struct draw_context *draw, struct pipe_context *pipe
int
draw_find_vs_output(const struct draw_context *draw,
uint semantic_name, uint semantic_index);
draw_find_shader_output(const struct draw_context *draw,
uint semantic_name, uint semantic_index);
uint
draw_num_vs_outputs(const struct draw_context *draw);
draw_num_shader_outputs(const struct draw_context *draw);
void
@ -112,6 +113,17 @@ void draw_delete_vertex_shader(struct draw_context *draw,
struct draw_vertex_shader *dvs);
/*
* Geometry shader functions
*/
struct draw_geometry_shader *
draw_create_geometry_shader(struct draw_context *draw,
const struct pipe_shader_state *shader);
void draw_bind_geometry_shader(struct draw_context *draw,
struct draw_geometry_shader *dvs);
void draw_delete_geometry_shader(struct draw_context *draw,
struct draw_geometry_shader *dvs);
/*
* Vertex data functions
@ -140,6 +152,7 @@ void draw_set_mapped_vertex_buffer(struct draw_context *draw,
unsigned attr, const void *buffer);
void draw_set_mapped_constant_buffer(struct draw_context *draw,
unsigned shader_type,
const void *buffer,
unsigned size );

View file

@ -0,0 +1,338 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#include "draw_gs.h"
#include "draw_private.h"
#include "draw_context.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_exec.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#define MAX_PRIM_VERTICES 6
/* fixme: move it from here */
#define MAX_PRIMITIVES 64
boolean
draw_gs_init( struct draw_context *draw )
{
draw->gs.machine = tgsi_exec_machine_create();
if (!draw->gs.machine)
return FALSE;
draw->gs.machine->Primitives = align_malloc(
MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16);
if (!draw->gs.machine->Primitives)
return FALSE;
memset(draw->gs.machine->Primitives, 0,
MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector));
return TRUE;
}
void draw_gs_set_constants( struct draw_context *draw,
const float (*constants)[4],
unsigned size )
{
}
struct draw_geometry_shader *
draw_create_geometry_shader(struct draw_context *draw,
const struct pipe_shader_state *state)
{
struct draw_geometry_shader *gs;
int i;
gs = CALLOC_STRUCT(draw_geometry_shader);
if (!gs)
return NULL;
gs->state = *state;
gs->state.tokens = tgsi_dup_tokens(state->tokens);
if (!gs->state.tokens) {
FREE(gs);
return NULL;
}
tgsi_scan_shader(state->tokens, &gs->info);
/* setup the defaults */
gs->input_primitive = PIPE_PRIM_TRIANGLES;
gs->output_primitive = PIPE_PRIM_TRIANGLE_STRIP;
gs->max_output_vertices = 32;
for (i = 0; i < gs->info.num_properties; ++i) {
if (gs->info.properties[i].name ==
TGSI_PROPERTY_GS_INPUT_PRIM)
gs->input_primitive = gs->info.properties[i].data[0];
else if (gs->info.properties[i].name ==
TGSI_PROPERTY_GS_OUTPUT_PRIM)
gs->output_primitive = gs->info.properties[i].data[0];
else if (gs->info.properties[i].name ==
TGSI_PROPERTY_GS_MAX_VERTICES)
gs->max_output_vertices = gs->info.properties[i].data[0];
}
gs->machine = draw->gs.machine;
if (gs)
{
uint i;
for (i = 0; i < gs->info.num_outputs; i++) {
if (gs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
gs->info.output_semantic_index[i] == 0)
gs->position_output = i;
}
}
return gs;
}
void draw_bind_geometry_shader(struct draw_context *draw,
struct draw_geometry_shader *dgs)
{
draw_do_flush(draw, DRAW_FLUSH_STATE_CHANGE);
if (dgs) {
draw->gs.geometry_shader = dgs;
draw->gs.num_gs_outputs = dgs->info.num_outputs;
draw->gs.position_output = dgs->position_output;
draw_geometry_shader_prepare(dgs, draw);
}
else {
draw->gs.geometry_shader = NULL;
draw->gs.num_gs_outputs = 0;
}
}
void draw_delete_geometry_shader(struct draw_context *draw,
struct draw_geometry_shader *dgs)
{
FREE(dgs);
}
static INLINE int num_vertices_for_prim(int prim)
{
switch(prim) {
case PIPE_PRIM_POINTS:
return 1;
case PIPE_PRIM_LINES:
return 2;
case PIPE_PRIM_LINE_LOOP:
return 2;
case PIPE_PRIM_LINE_STRIP:
return 2;
case PIPE_PRIM_TRIANGLES:
return 3;
case PIPE_PRIM_TRIANGLE_STRIP:
return 3;
case PIPE_PRIM_TRIANGLE_FAN:
return 3;
case PIPE_PRIM_LINES_ADJACENCY:
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
return 4;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
return 6;
default:
assert(!"Bad geometry shader input");
return 0;
}
}
static void draw_fetch_geometry_input(struct draw_geometry_shader *shader,
int start_primitive,
int num_primitives,
const float (*input_ptr)[4],
unsigned input_vertex_stride,
unsigned inputs_from_vs)
{
struct tgsi_exec_machine *machine = shader->machine;
unsigned slot, vs_slot, k, j;
unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
int idx = 0;
for (slot = 0, vs_slot = 0; slot < shader->info.num_inputs; slot++) {
debug_printf("Slot = %d (semantic = %d)\n", slot,
shader->info.input_semantic_name[slot]);
if (shader->info.input_semantic_name[slot] ==
TGSI_SEMANTIC_VERTICES) {
for (j = 0; j < num_primitives; ++j) {
machine->Inputs[idx].xyzw[0].f[j] = (float)num_vertices;
machine->Inputs[idx].xyzw[1].f[j] = (float)num_vertices;
machine->Inputs[idx].xyzw[2].f[j] = (float)num_vertices;
machine->Inputs[idx].xyzw[3].f[j] = (float)num_vertices;
}
++idx;
} else {
for (j = 0; j < num_primitives; ++j) {
int vidx = idx;
const float (*prim_ptr)[4];
debug_printf(" %d) Prim (num_verts = %d)\n", start_primitive + j,
num_vertices);
prim_ptr = (const float (*)[4])(
(const char *)input_ptr +
(j * num_vertices * input_vertex_stride));
for (k = 0; k < num_vertices; ++k, ++vidx) {
const float (*input)[4];
input = (const float (*)[4])(
(const char *)prim_ptr + (k * input_vertex_stride));
debug_printf("\t%d)(%d) Input vert:\n", vidx, k);
#if 1
assert(!util_is_inf_or_nan(input[vs_slot][0]));
assert(!util_is_inf_or_nan(input[vs_slot][1]));
assert(!util_is_inf_or_nan(input[vs_slot][2]));
assert(!util_is_inf_or_nan(input[vs_slot][3]));
#endif
machine->Inputs[vidx].xyzw[0].f[j] = input[vs_slot][0];
machine->Inputs[vidx].xyzw[1].f[j] = input[vs_slot][1];
machine->Inputs[vidx].xyzw[2].f[j] = input[vs_slot][2];
machine->Inputs[vidx].xyzw[3].f[j] = input[vs_slot][3];
#if 0
debug_printf("\t\t%d %f %f %f %f\n", slot,
machine->Inputs[vidx].xyzw[0].f[j],
machine->Inputs[vidx].xyzw[1].f[j],
machine->Inputs[vidx].xyzw[2].f[j],
machine->Inputs[vidx].xyzw[3].f[j]);
#endif
}
}
++vs_slot;
idx += num_vertices;
}
}
}
static INLINE void
draw_geometry_fetch_outputs(struct draw_geometry_shader *shader,
int num_primitives,
float (*output)[4],
unsigned vertex_size)
{
struct tgsi_exec_machine *machine = shader->machine;
unsigned prim_idx, j, slot;
/* Unswizzle all output results.
*/
/* FIXME: handle all the primitives produced by the gs, not just
* the first one
unsigned prim_count =
mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];*/
for (prim_idx = 0; prim_idx < num_primitives; ++prim_idx) {
unsigned num_verts_per_prim = machine->Primitives[0];
for (j = 0; j < num_verts_per_prim; j++) {
int idx = (prim_idx * num_verts_per_prim + j) *
shader->info.num_outputs;
#ifdef DEBUG_OUTPUTS
debug_printf("%d) Output vert:\n", idx);
#endif
for (slot = 0; slot < shader->info.num_outputs; slot++) {
output[slot][0] = machine->Outputs[idx + slot].xyzw[0].f[prim_idx];
output[slot][1] = machine->Outputs[idx + slot].xyzw[1].f[prim_idx];
output[slot][2] = machine->Outputs[idx + slot].xyzw[2].f[prim_idx];
output[slot][3] = machine->Outputs[idx + slot].xyzw[3].f[prim_idx];
#ifdef DEBUG_OUTPUTS
debug_printf("\t%d: %f %f %f %f\n", slot,
output[slot][0],
output[slot][1],
output[slot][2],
output[slot][3]);
#endif
debug_assert(!util_is_inf_or_nan(output[slot][0]));
}
output = (float (*)[4])((char *)output + vertex_size);
}
}
}
void draw_geometry_shader_run(struct draw_geometry_shader *shader,
const float (*input)[4],
float (*output)[4],
const float (*constants)[4],
unsigned count,
unsigned input_stride,
unsigned vertex_size)
{
struct tgsi_exec_machine *machine = shader->machine;
unsigned int i;
unsigned num_vertices = num_vertices_for_prim(shader->input_primitive);
unsigned num_primitives = count/num_vertices;
unsigned inputs_from_vs = 0;
machine->Consts = constants;
for (i = 0; i < shader->info.num_inputs; ++i) {
if (shader->info.input_semantic_name[i] != TGSI_SEMANTIC_VERTICES &&
shader->info.input_semantic_name[i] != TGSI_SEMANTIC_PRIMID)
++inputs_from_vs;
}
for (i = 0; i < num_primitives; ++i) {
unsigned int max_primitives = 1;
draw_fetch_geometry_input(shader, i, max_primitives, input,
input_stride, inputs_from_vs);
tgsi_set_exec_mask(machine,
1,
max_primitives > 1,
max_primitives > 2,
max_primitives > 3);
/* run interpreter */
tgsi_exec_machine_run(machine);
draw_geometry_fetch_outputs(shader, max_primitives,
output, vertex_size);
}
}
void draw_geometry_shader_delete(struct draw_geometry_shader *shader)
{
FREE((void*) shader->state.tokens);
FREE(shader);
}
void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
struct draw_context *draw)
{
if (shader->machine->Tokens != shader->state.tokens) {
tgsi_exec_machine_bind_shader(shader->machine,
shader->state.tokens,
draw->gs.num_samplers,
draw->gs.samplers);
}
}

View file

@ -0,0 +1,76 @@
/**************************************************************************
*
* 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.
*
**************************************************************************/
#ifndef DRAW_GS_H
#define DRAW_GS_H
#include "draw_context.h"
#include "draw_private.h"
#define MAX_TGSI_PRIMITIVES 4
struct draw_context;
/**
* Private version of the compiled geometry shader
*/
struct draw_geometry_shader {
struct draw_context *draw;
struct tgsi_exec_machine *machine;
/* This member will disappear shortly:*/
struct pipe_shader_state state;
struct tgsi_shader_info info;
unsigned position_output;
unsigned max_output_vertices;
unsigned input_primitive;
unsigned output_primitive;
/* Extracted from shader:
*/
const float (*immediates)[4];
};
void draw_geometry_shader_run(struct draw_geometry_shader *shader,
const float (*input)[4],
float (*output)[4],
const float (*constants)[4],
unsigned count,
unsigned input_stride,
unsigned output_stride);
void draw_geometry_shader_prepare(struct draw_geometry_shader *shader,
struct draw_context *draw);
void draw_geometry_shader_delete(struct draw_geometry_shader *shader);
#endif

View file

@ -660,13 +660,13 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
}
/* update vertex attrib info */
aaline->tex_slot = draw->vs.num_vs_outputs;
aaline->pos_slot = draw->vs.position_output;
aaline->tex_slot = draw_current_shader_outputs(draw);
aaline->pos_slot = draw_current_shader_position_output(draw);;
/* advertise the extra post-transformed vertex attribute */
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
draw->extra_vp_outputs.slot = aaline->tex_slot;
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_shader_outputs.semantic_index = aaline->fs->generic_attrib;
draw->extra_shader_outputs.slot = aaline->tex_slot;
/* how many samplers? */
/* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
@ -707,7 +707,7 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
aaline->state.texture);
draw->suspend_flushing = FALSE;
draw->extra_vp_outputs.slot = 0;
draw->extra_shader_outputs.slot = 0;
}

View file

@ -687,14 +687,14 @@ aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
bind_aapoint_fragment_shader(aapoint);
/* update vertex attrib info */
aapoint->tex_slot = draw->vs.num_vs_outputs;
aapoint->tex_slot = draw_current_shader_outputs(draw);
assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
aapoint->pos_slot = draw->vs.position_output;
aapoint->pos_slot = draw_current_shader_position_output(draw);
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
draw->extra_vp_outputs.slot = aapoint->tex_slot;
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_shader_outputs.semantic_index = aapoint->fs->generic_attrib;
draw->extra_shader_outputs.slot = aapoint->tex_slot;
/* find psize slot in post-transform vertex */
aapoint->psize_slot = -1;
@ -731,7 +731,7 @@ aapoint_flush(struct draw_stage *stage, unsigned flags)
aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
draw->suspend_flushing = FALSE;
draw->extra_vp_outputs.slot = 0;
draw->extra_shader_outputs.slot = 0;
}

View file

@ -114,8 +114,8 @@ static void interp( const struct clipper *clip,
const struct vertex_header *out,
const struct vertex_header *in )
{
const unsigned nr_attrs = clip->stage.draw->vs.num_vs_outputs;
const unsigned pos_attr = clip->stage.draw->vs.position_output;
const unsigned nr_attrs = draw_current_shader_outputs(clip->stage.draw);
const unsigned pos_attr = draw_current_shader_position_output(clip->stage.draw);
unsigned j;
/* Vertex header.

View file

@ -55,7 +55,7 @@ static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
static void cull_tri( struct draw_stage *stage,
struct prim_header *header )
{
const unsigned pos = stage->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(stage->draw);
/* Window coords: */
const float *v0 = header->v[0]->data[pos];

View file

@ -63,7 +63,7 @@ static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
static void do_offset_tri( struct draw_stage *stage,
struct prim_header *header )
{
const unsigned pos = stage->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(stage->draw);
struct offset_stage *offset = offset_stage(stage);
float inv_det = 1.0f / header->det;

View file

@ -73,7 +73,8 @@ screen_interp( struct draw_context *draw,
const struct vertex_header *v1 )
{
uint attr;
for (attr = 0; attr < draw->vs.num_vs_outputs; attr++) {
int num_outputs = draw_current_shader_outputs(draw);
for (attr = 0; attr < num_outputs; attr++) {
const float *val0 = v0->data[attr];
const float *val1 = v1->data[attr];
float *newv = dst->data[attr];
@ -121,7 +122,7 @@ stipple_line(struct draw_stage *stage, struct prim_header *header)
struct stipple_stage *stipple = stipple_stage(stage);
struct vertex_header *v0 = header->v[0];
struct vertex_header *v1 = header->v[1];
const unsigned pos = stage->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(stage->draw);
const float *pos0 = v0->data[pos];
const float *pos1 = v1->data[pos];
float start = 0;

View file

@ -59,7 +59,7 @@ static void wideline_line( struct draw_stage *stage,
struct prim_header *header )
{
/*const struct wideline_stage *wide = wideline_stage(stage);*/
const unsigned pos = stage->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(stage->draw);
const float half_width = 0.5f * stage->draw->rasterizer->line_width;
struct prim_header tri;

View file

@ -112,7 +112,7 @@ static void set_texcoords(const struct widepoint_stage *wide,
if (wide->point_coord_fs_input >= 0) {
/* put gl_PointCoord into the extra vertex slot */
uint slot = wide->stage.draw->extra_vp_outputs.slot;
uint slot = wide->stage.draw->extra_shader_outputs.slot;
v->data[slot][0] = tc[0];
v->data[slot][1] = tc[1];
v->data[slot][2] = 0.0F;
@ -130,7 +130,7 @@ static void widepoint_point( struct draw_stage *stage,
struct prim_header *header )
{
const struct widepoint_stage *wide = widepoint_stage(stage);
const unsigned pos = stage->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(stage->draw);
const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
float half_size;
float left_adj, right_adj, bot_adj, top_adj;
@ -257,13 +257,13 @@ static void widepoint_first_point( struct draw_stage *stage,
wide->point_coord_fs_input = find_pntc_input_attrib(draw);
/* setup extra vp output (point coord implemented as a texcoord) */
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_vp_outputs.semantic_index = 0;
draw->extra_vp_outputs.slot = draw->vs.num_vs_outputs;
draw->extra_shader_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
draw->extra_shader_outputs.semantic_index = 0;
draw->extra_shader_outputs.slot = draw_current_shader_outputs(draw);
}
else {
wide->point_coord_fs_input = -1;
draw->extra_vp_outputs.slot = 0;
draw->extra_shader_outputs.slot = 0;
}
wide->psize_slot = -1;
@ -287,7 +287,7 @@ static void widepoint_flush( struct draw_stage *stage, unsigned flags )
{
stage->point = widepoint_first_point;
stage->next->flush( stage->next, flags );
stage->draw->extra_vp_outputs.slot = 0;
stage->draw->extra_shader_outputs.slot = 0;
}

View file

@ -152,8 +152,9 @@ struct draw_context
/** vertex arrays */
const void *vbuffer[PIPE_MAX_ATTRIBS];
/** constant buffer (for vertex shader) */
const void *constants;
/** constant buffer (for vertex/geometry shader) */
const void *vs_constants;
const void *gs_constants;
} user;
boolean test_fse; /* enable FSE even though its not correct (eg for softpipe) */
@ -211,6 +212,18 @@ struct draw_context
struct translate_cache *emit_cache;
} vs;
struct {
struct draw_geometry_shader *geometry_shader;
uint num_gs_outputs; /**< convenience, from geometry_shader */
uint position_output;
/** TGSI program interpreter runtime state */
struct tgsi_exec_machine *machine;
uint num_samplers;
struct tgsi_sampler **samplers;
} gs;
/* Clip derived state:
*/
float plane[12][4];
@ -222,7 +235,7 @@ struct draw_context
uint semantic_name;
uint semantic_index;
int slot;
} extra_vp_outputs;
} extra_shader_outputs;
unsigned reduced_prim;
@ -245,6 +258,19 @@ void draw_vs_set_constants( struct draw_context *,
/*******************************************************************************
* Geometry shading code:
*/
boolean draw_gs_init( struct draw_context *draw );
void draw_gs_set_constants( struct draw_context *,
const float (*constants)[4],
unsigned size );
/*******************************************************************************
* Common shading code:
*/
int draw_current_shader_outputs(struct draw_context *draw);
int draw_current_shader_position_output(struct draw_context *draw);
/*******************************************************************************
* Vertex processing (was passthrough) code:

View file

@ -32,6 +32,7 @@
#include "draw/draw_vertex.h"
#include "draw/draw_pt.h"
#include "draw/draw_vs.h"
#include "draw/draw_gs.h"
#include "translate/translate.h"
@ -119,7 +120,8 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
{
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vs.vertex_shader;
struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( fetch_count, 4 );
@ -147,13 +149,21 @@ static void fetch_pipeline_run( struct draw_pt_middle_end *middle,
*/
if (opt & PT_SHADE)
{
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
vshader->run_linear(vshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.vs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
if (gshader)
draw_geometry_shader_run(gshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.gs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
@ -196,6 +206,7 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vs.vertex_shader;
struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( count, 4 );
@ -226,10 +237,19 @@ static void fetch_pipeline_linear_run( struct draw_pt_middle_end *middle,
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.constants,
(const float (*)[4])draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
if (geometry_shader)
draw_geometry_shader_run(geometry_shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.gs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,
@ -270,6 +290,7 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
struct fetch_pipeline_middle_end *fpme = (struct fetch_pipeline_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *shader = draw->vs.vertex_shader;
struct draw_geometry_shader *geometry_shader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( count, 4 );
@ -296,10 +317,19 @@ static boolean fetch_pipeline_linear_run_elts( struct draw_pt_middle_end *middle
shader->run_linear(shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.constants,
(const float (*)[4])draw->pt.user.vs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
if (geometry_shader)
draw_geometry_shader_run(geometry_shader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
(const float (*)[4])draw->pt.user.gs_constants,
count,
fpme->vertex_size,
fpme->vertex_size);
}
if (draw_pt_post_vs_run( fpme->post_vs,

View file

@ -100,7 +100,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
struct vertex_header *out = vertices;
const float *scale = pvs->draw->viewport.scale;
const float *trans = pvs->draw->viewport.translate;
const unsigned pos = pvs->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(pvs->draw);
unsigned clipped = 0;
unsigned j;
@ -190,7 +190,7 @@ static boolean post_vs_viewport( struct pt_post_vs *pvs,
struct vertex_header *out = vertices;
const float *scale = pvs->draw->viewport.scale;
const float *trans = pvs->draw->viewport.translate;
const unsigned pos = pvs->draw->vs.position_output;
const unsigned pos = draw_current_shader_position_output(pvs->draw);
unsigned j;
if (0) debug_printf("%s\n", __FUNCTION__);

View file

@ -50,16 +50,32 @@ void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr)
*first = 2;
*incr = 1;
break;
case PIPE_PRIM_LINES_ADJACENCY:
*first = 4;
*incr = 2;
break;
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
*first = 4;
*incr = 1;
break;
case PIPE_PRIM_TRIANGLES:
*first = 3;
*incr = 3;
break;
case PIPE_PRIM_TRIANGLES_ADJACENCY:
*first = 6;
*incr = 3;
break;
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_TRIANGLE_FAN:
case PIPE_PRIM_POLYGON:
*first = 3;
*incr = 1;
break;
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
*first = 6;
*incr = 1;
break;
case PIPE_PRIM_QUADS:
*first = 4;
*incr = 4;

View file

@ -36,6 +36,10 @@ static void FUNC(struct draw_pt_front_end *frontend,
case PIPE_PRIM_TRIANGLE_STRIP:
case PIPE_PRIM_QUADS:
case PIPE_PRIM_QUAD_STRIP:
case PIPE_PRIM_LINES_ADJACENCY:
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
case PIPE_PRIM_TRIANGLES_ADJACENCY:
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
for (j = 0; j < count;) {
unsigned remaining = count - j;
unsigned nr = trim( MIN2(varray->driver_fetch_max, remaining), first, incr );

View file

@ -147,11 +147,12 @@ static void PIPE_CDECL vsvg_run_elts( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
(const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
(const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);
/* FIXME: geometry shading? */
if (vsvg->base.key.clip) {
/* not really handling clipping, just do the rhw so we can
@ -207,7 +208,7 @@ static void PIPE_CDECL vsvg_run_linear( struct draw_vs_varient *varient,
vsvg->base.vs->run_linear( vsvg->base.vs,
temp_buffer,
temp_buffer,
(const float (*)[4])vsvg->base.vs->draw->pt.user.constants,
(const float (*)[4])vsvg->base.vs->draw->pt.user.vs_constants,
count,
temp_vertex_stride,
temp_vertex_stride);

View file

@ -122,7 +122,9 @@ static const char *semantic_names[] =
"GENERIC",
"NORMAL",
"FACE",
"EDGEFLAG"
"EDGEFLAG",
"VERTICES_IN",
"PRIM_ID"
};
static const char *immediate_type_names[] =

View file

@ -372,6 +372,7 @@ tgsi_exec_machine_create( void )
memset(mach, 0, sizeof(*mach));
mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
/* Setup constants. */
@ -1468,6 +1469,15 @@ store_dest(
index = mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0]
+ reg->Register.Index;
dst = &mach->Outputs[offset + index].xyzw[chan_index];
#if 0
if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) {
fprintf(stderr, "STORING OUT[%d] mask(%d), = (", index, execmask);
for (i = 0; i < QUAD_SIZE; i++)
if (execmask & (1 << i))
fprintf(stderr, "%f, ", chan->f[i]);
fprintf(stderr, ")\n");
}
#endif
break;
case TGSI_FILE_TEMPORARY:
@ -1638,6 +1648,35 @@ exec_kilp(struct tgsi_exec_machine *mach,
mach->Temps[TEMP_KILMASK_I].xyzw[TEMP_KILMASK_C].u[0] |= kilmask;
}
static void
emit_vertex(struct tgsi_exec_machine *mach)
{
/* FIXME: check for exec mask correctly
unsigned i;
for (i = 0; i < QUAD_SIZE; ++i) {
if ((mach->ExecMask & (1 << i)))
*/
if (mach->ExecMask) {
mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += mach->NumOutputs;
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
}
}
static void
emit_primitive(struct tgsi_exec_machine *mach)
{
unsigned *prim_count = &mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0];
/* FIXME: check for exec mask correctly
unsigned i;
for (i = 0; i < QUAD_SIZE; ++i) {
if ((mach->ExecMask & (1 << i)))
*/
if (mach->ExecMask) {
++(*prim_count);
debug_assert((*prim_count * mach->NumOutputs) < mach->MaxGeometryShaderOutputs);
mach->Primitives[*prim_count] = 0;
}
}
/*
* Fetch a four texture samples using STR texture coordinates.
@ -3087,13 +3126,11 @@ exec_instruction(
break;
case TGSI_OPCODE_EMIT:
mach->Temps[TEMP_OUTPUT_I].xyzw[TEMP_OUTPUT_C].u[0] += 16;
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]]++;
emit_vertex(mach);
break;
case TGSI_OPCODE_ENDPRIM:
mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]++;
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
emit_primitive(mach);
break;
case TGSI_OPCODE_BGNFOR:

View file

@ -191,6 +191,14 @@ struct tgsi_exec_labels
*/
#define TGSI_EXEC_MAX_CONST_BUFFER 4096
/* The maximum number of vertices per primitive */
#define TGSI_MAX_PRIM_VERTICES 6
/* The maximum number of primitives to be generated */
#define TGSI_MAX_PRIMITIVES 64
/* The maximum total number of vertices */
#define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS)
/** function call/activation record */
struct tgsi_call_record
@ -201,7 +209,6 @@ struct tgsi_call_record
uint ReturnAddr;
};
/**
* Run-time virtual machine state for executing TGSI shader.
*/
@ -214,8 +221,8 @@ struct tgsi_exec_machine
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
struct tgsi_exec_vector Inputs[PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Outputs[PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES];
struct tgsi_exec_vector *Addrs;
struct tgsi_exec_vector *Predicates;
@ -229,6 +236,8 @@ struct tgsi_exec_machine
/* GEOMETRY processor only. */
unsigned *Primitives;
unsigned NumOutputs;
unsigned MaxGeometryShaderOutputs;
/* FRAGMENT processor only. */
const struct tgsi_interp_coef *InterpCoefs;

View file

@ -791,7 +791,9 @@ static const char *semantic_names[TGSI_SEMANTIC_COUNT] =
"PSIZE",
"GENERIC",
"NORMAL",
"FACE"
"FACE",
"VERTICES_IN",
"PRIM_ID"
};
static const char *interpolate_names[TGSI_INTERPOLATE_COUNT] =

View file

@ -59,7 +59,7 @@ cell_map_constant_buffers(struct cell_context *sp)
}
}
draw_set_mapped_constant_buffer(sp->draw,
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
sp->mapped_constants[PIPE_SHADER_VERTEX],
sp->constants[PIPE_SHADER_VERTEX].buffer->size);
}

View file

@ -66,7 +66,7 @@ calculate_vertex_layout( struct cell_context *cell )
vinfo->num_attribs = 0;
/* we always want to emit vertex pos */
src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_POSITION, 0);
src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_POSITION, 0);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
@ -82,14 +82,14 @@ calculate_vertex_layout( struct cell_context *cell )
break;
case TGSI_SEMANTIC_COLOR:
src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_COLOR,
src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_COLOR,
fs->info.input_semantic_index[i]);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
break;
case TGSI_SEMANTIC_FOG:
src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_FOG, 0);
src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_FOG, 0);
#if 1
if (src < 0) /* XXX temp hack, try demos/fogcoord.c with this */
src = 0;
@ -100,7 +100,7 @@ calculate_vertex_layout( struct cell_context *cell )
case TGSI_SEMANTIC_GENERIC:
/* this includes texcoords and varying vars */
src = draw_find_vs_output(cell->draw, TGSI_SEMANTIC_GENERIC,
src = draw_find_shader_output(cell->draw, TGSI_SEMANTIC_GENERIC,
fs->info.input_semantic_index[i]);
assert(src >= 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);

View file

@ -331,7 +331,7 @@ cell_emit_state(struct cell_context *cell)
const struct draw_context *const draw = cell->draw;
struct cell_shader_info info;
info.num_outputs = draw_num_vs_outputs(draw);
info.num_outputs = draw_num_shader_outputs(draw);
info.declarations = (uintptr_t) draw->vs.machine.Declarations;
info.num_declarations = draw->vs.machine.NumDeclarations;
info.instructions = (uintptr_t) draw->vs.machine.Instructions;

View file

@ -84,7 +84,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
}
draw_set_mapped_constant_buffer(draw,
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
i915->current.constants[PIPE_SHADER_VERTEX],
(i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
4 * sizeof(float)));

View file

@ -84,7 +84,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
/* pos */
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0);
if (needW) {
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src);
vinfo.hwfmt[0] |= S4_VFMT_XYZW;
@ -101,21 +101,21 @@ static void calculate_vertex_layout( struct i915_context *i915 )
/* primary color */
if (colors[0]) {
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0);
draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_COLOR;
}
/* secondary color */
if (colors[1]) {
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1);
draw_emit_vertex_attr(&vinfo, EMIT_4UB, colorInterp, src);
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG;
}
/* fog coord, not fog blend factor */
if (fog) {
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0);
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM;
}
@ -125,7 +125,7 @@ static void calculate_vertex_layout( struct i915_context *i915 )
uint hwtc;
if (texCoords[i]) {
hwtc = TEXCOORDFMT_4D;
src = draw_find_vs_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
}
else {

View file

@ -66,7 +66,7 @@ llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
/* compute vertex layout now */
const struct lp_fragment_shader *lpfs = llvmpipe->fs;
struct vertex_info *vinfo_vbuf = &llvmpipe->vertex_info_vbuf;
const uint num = draw_num_vs_outputs(llvmpipe->draw);
const uint num = draw_current_shader_outputs(llvmpipe->draw);
uint i;
/* Tell draw_vbuf to simply emit the whole post-xform vertex

View file

@ -734,7 +734,8 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
}
if(shader == PIPE_SHADER_VERTEX) {
draw_set_mapped_constant_buffer(llvmpipe->draw, data, size);
draw_set_mapped_constant_buffer(llvmpipe->draw, PIPE_SHADER_VERTEX,
data, size);
}
llvmpipe->dirty |= LP_NEW_CONSTANTS;

View file

@ -45,7 +45,7 @@ boolean nv04_draw_elements( struct pipe_context *pipe,
draw_set_mapped_element_buffer(draw, 0, NULL);
}
draw_set_mapped_constant_buffer(draw,
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
nv04->constbuf[PIPE_SHADER_VERTEX],
nv04->constbuf_nr[PIPE_SHADER_VERTEX]);

View file

@ -45,6 +45,7 @@ boolean nv10_draw_elements( struct pipe_context *pipe,
}
draw_set_mapped_constant_buffer(draw,
PIPE_SHADER_VERTEX,
nv10->constbuf[PIPE_SHADER_VERTEX],
nv10->constbuf_nr[PIPE_SHADER_VERTEX]);

View file

@ -228,7 +228,7 @@ static void nv20_vertex_layout(struct nv20_context *nv20)
}
/* always do position */ {
src = draw_find_vs_output(dc, TGSI_SEMANTIC_POSITION, 0);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_POSITION, 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR, src);
vinfo->hwfmt[0] |= (1 << 0);
}
@ -237,19 +237,19 @@ static void nv20_vertex_layout(struct nv20_context *nv20)
for (i = 4; i < 6; i++) {
if (!generics[i])
continue;
src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
vinfo->hwfmt[0] |= (1 << (i - 3));
}
if (colors[0]) {
src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 0);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 0);
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
vinfo->hwfmt[0] |= (1 << 3);
}
if (colors[1]) {
src = draw_find_vs_output(dc, TGSI_SEMANTIC_COLOR, 1);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_COLOR, 1);
draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
vinfo->hwfmt[0] |= (1 << 4);
}
@ -258,7 +258,7 @@ static void nv20_vertex_layout(struct nv20_context *nv20)
for (i = 6; i < 10; i++) {
if (!generics[i])
continue;
src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
vinfo->hwfmt[0] |= (1 << (i - 1));
}
@ -267,7 +267,7 @@ static void nv20_vertex_layout(struct nv20_context *nv20)
for (i = 0; i < 4; i++) {
if (!generics[i])
continue;
src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
vinfo->hwfmt[0] |= (1 << (i + 9));
}
@ -276,13 +276,13 @@ static void nv20_vertex_layout(struct nv20_context *nv20)
for (i = 10; i < 12; i++) {
if (!generics[i])
continue;
src = draw_find_vs_output(dc, TGSI_SEMANTIC_GENERIC, i);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_GENERIC, i);
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
vinfo->hwfmt[0] |= (1 << (i + 3));
}
if (fog) {
src = draw_find_vs_output(dc, TGSI_SEMANTIC_FOG, 0);
src = draw_find_shader_output(dc, TGSI_SEMANTIC_FOG, 0);
draw_emit_vertex_attr(vinfo, EMIT_1F, INTERP_PERSPECTIVE, src);
vinfo->hwfmt[0] |= (1 << 15);
}

View file

@ -45,7 +45,7 @@ boolean nv20_draw_elements( struct pipe_context *pipe,
draw_set_mapped_element_buffer(draw, 0, NULL);
}
draw_set_mapped_constant_buffer(draw,
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX,
nv20->constbuf[PIPE_SHADER_VERTEX],
nv20->constbuf_nr[PIPE_SHADER_VERTEX]);

View file

@ -261,7 +261,8 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe,
map = pipe_buffer_map(pscreen,
nv40->constbuf[PIPE_SHADER_VERTEX],
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_constant_buffer(nv40->draw, map, nr);
draw_set_mapped_constant_buffer(nv40->draw, PIPE_SHADER_VERTEX,
map, nr);
}
draw_arrays(nv40->draw, mode, start, count);
@ -285,7 +286,7 @@ static INLINE void
emit_attrib(struct nv40_context *nv40, unsigned hw, unsigned emit,
unsigned semantic, unsigned index)
{
unsigned draw_out = draw_find_vs_output(nv40->draw, semantic, index);
unsigned draw_out = draw_find_shader_output(nv40->draw, semantic, index);
unsigned a = nv40->swtnl.nr_attribs++;
nv40->swtnl.hw[a] = hw;

View file

@ -222,6 +222,10 @@ softpipe_create( struct pipe_screen *screen )
softpipe->pipe.bind_vs_state = softpipe_bind_vs_state;
softpipe->pipe.delete_vs_state = softpipe_delete_vs_state;
softpipe->pipe.create_gs_state = softpipe_create_gs_state;
softpipe->pipe.bind_gs_state = softpipe_bind_gs_state;
softpipe->pipe.delete_gs_state = softpipe_delete_gs_state;
softpipe->pipe.set_blend_color = softpipe_set_blend_color;
softpipe->pipe.set_clip_state = softpipe_set_clip_state;
softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer;

View file

@ -58,6 +58,7 @@ struct softpipe_context {
struct pipe_rasterizer_state *rasterizer;
struct sp_fragment_shader *fs;
struct sp_vertex_shader *vs;
struct sp_geometry_shader *gs;
/** Other rendering state */
struct pipe_blend_color blend_color;

View file

@ -48,7 +48,7 @@ static void
softpipe_map_constant_buffers(struct softpipe_context *sp)
{
struct pipe_winsys *ws = sp->pipe.winsys;
uint i, size;
uint i, vssize, gssize;
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
if (sp->constants[i].buffer && sp->constants[i].buffer->size)
@ -57,13 +57,21 @@ softpipe_map_constant_buffers(struct softpipe_context *sp)
}
if (sp->constants[PIPE_SHADER_VERTEX].buffer)
size = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
vssize = sp->constants[PIPE_SHADER_VERTEX].buffer->size;
else
size = 0;
vssize = 0;
draw_set_mapped_constant_buffer(sp->draw,
if (sp->constants[PIPE_SHADER_GEOMETRY].buffer)
gssize = sp->constants[PIPE_SHADER_GEOMETRY].buffer->size;
else
gssize = 0;
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX,
sp->mapped_constants[PIPE_SHADER_VERTEX],
size);
vssize);
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY,
sp->mapped_constants[PIPE_SHADER_GEOMETRY],
gssize);
}
@ -78,9 +86,10 @@ softpipe_unmap_constant_buffers(struct softpipe_context *sp)
*/
draw_flush(sp->draw);
draw_set_mapped_constant_buffer(sp->draw, NULL, 0);
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_VERTEX, NULL, 0);
draw_set_mapped_constant_buffer(sp->draw, PIPE_SHADER_GEOMETRY, NULL, 0);
for (i = 0; i < 2; i++) {
for (i = 0; i < PIPE_SHADER_TYPES; i++) {
if (sp->constants[i].buffer && sp->constants[i].buffer->size)
ws->buffer_unmap(ws, sp->constants[i].buffer);
sp->mapped_constants[i] = NULL;

View file

@ -89,6 +89,8 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return 13; /* max 4Kx4K */
case PIPE_CAP_TGSI_CONT_SUPPORTED:
return 1;
case PIPE_CAP_GEOMETRY_SHADER4:
return 1;
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
return 1;
default:

View file

@ -1268,7 +1268,7 @@ void sp_setup_prepare( struct setup_context *setup )
}
/* Note: nr_attrs is only used for debugging (vertex printing) */
setup->nr_vertex_attrs = draw_num_vs_outputs(sp->draw);
setup->nr_vertex_attrs = draw_num_shader_outputs(sp->draw);
sp->quad.first->begin( sp->quad.first );

View file

@ -50,6 +50,7 @@
#define SP_NEW_VERTEX 0x1000
#define SP_NEW_VS 0x2000
#define SP_NEW_QUERY 0x4000
#define SP_NEW_GS 0x8000
struct tgsi_sampler;
@ -90,6 +91,11 @@ struct sp_vertex_shader {
int max_sampler; /* -1 if no samplers */
};
/** Subclass of pipe_shader_state */
struct sp_geometry_shader {
struct pipe_shader_state shader;
struct draw_geometry_shader *draw_data;
};
void *
@ -143,6 +149,10 @@ void *softpipe_create_vs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_vs_state(struct pipe_context *, void *);
void softpipe_delete_vs_state(struct pipe_context *, void *);
void *softpipe_create_gs_state(struct pipe_context *,
const struct pipe_shader_state *);
void softpipe_bind_gs_state(struct pipe_context *, void *);
void softpipe_delete_gs_state(struct pipe_context *, void *);
void softpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );

View file

@ -67,7 +67,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
/* compute vertex layout now */
const struct sp_fragment_shader *spfs = softpipe->fs;
struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
const uint num = draw_num_vs_outputs(softpipe->draw);
const uint num = draw_current_shader_outputs(softpipe->draw);
uint i;
/* Tell draw_vbuf to simply emit the whole post-xform vertex
@ -117,13 +117,13 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
}
/* this includes texcoords and varying vars */
src = draw_find_vs_output(softpipe->draw,
spfs->info.input_semantic_name[i],
spfs->info.input_semantic_index[i]);
src = draw_find_shader_output(softpipe->draw,
spfs->info.input_semantic_name[i],
spfs->info.input_semantic_index[i]);
draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
}
softpipe->psize_slot = draw_find_vs_output(softpipe->draw,
softpipe->psize_slot = draw_find_shader_output(softpipe->draw,
TGSI_SEMANTIC_PSIZE, 0);
if (softpipe->psize_slot > 0) {
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,

View file

@ -165,3 +165,62 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
softpipe->dirty |= SP_NEW_CONSTANTS;
}
void *
softpipe_create_gs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_geometry_shader *state;
state = CALLOC_STRUCT(sp_geometry_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_geometry_shader(softpipe->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
softpipe_bind_gs_state(struct pipe_context *pipe, void *gs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
softpipe->gs = (struct sp_geometry_shader *)gs;
draw_bind_geometry_shader(softpipe->draw,
(softpipe->gs ? softpipe->gs->draw_data : NULL));
softpipe->dirty |= SP_NEW_GS;
}
void
softpipe_delete_gs_state(struct pipe_context *pipe, void *gs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
struct sp_geometry_shader *state =
(struct sp_geometry_shader *)gs;
draw_delete_geometry_shader(softpipe->draw, state->draw_data);
FREE(state);
}

View file

@ -90,7 +90,7 @@ svga_swtnl_draw_range_elements(struct svga_context *svga,
PIPE_BUFFER_USAGE_CPU_READ);
assert(map);
draw_set_mapped_constant_buffer(
draw,
draw, PIPE_SHADER_VERTEX,
map,
svga->curr.cb[PIPE_SHADER_VERTEX]->size);
}

View file

@ -142,6 +142,12 @@ struct pipe_context {
const struct pipe_shader_state *);
void (*bind_vs_state)(struct pipe_context *, void *);
void (*delete_vs_state)(struct pipe_context *, void *);
void * (*create_gs_state)(struct pipe_context *,
const struct pipe_shader_state *);
void (*bind_gs_state)(struct pipe_context *, void *);
void (*delete_gs_state)(struct pipe_context *, void *);
/*@}*/
/**

View file

@ -321,23 +321,28 @@ enum pipe_transfer_usage {
*/
#define PIPE_SHADER_VERTEX 0
#define PIPE_SHADER_FRAGMENT 1
#define PIPE_SHADER_TYPES 2
#define PIPE_SHADER_GEOMETRY 2
#define PIPE_SHADER_TYPES 3
/**
* Primitive types:
*/
#define PIPE_PRIM_POINTS 0
#define PIPE_PRIM_LINES 1
#define PIPE_PRIM_LINE_LOOP 2
#define PIPE_PRIM_LINE_STRIP 3
#define PIPE_PRIM_TRIANGLES 4
#define PIPE_PRIM_TRIANGLE_STRIP 5
#define PIPE_PRIM_TRIANGLE_FAN 6
#define PIPE_PRIM_QUADS 7
#define PIPE_PRIM_QUAD_STRIP 8
#define PIPE_PRIM_POLYGON 9
#define PIPE_PRIM_MAX 10
#define PIPE_PRIM_POINTS 0
#define PIPE_PRIM_LINES 1
#define PIPE_PRIM_LINE_LOOP 2
#define PIPE_PRIM_LINE_STRIP 3
#define PIPE_PRIM_TRIANGLES 4
#define PIPE_PRIM_TRIANGLE_STRIP 5
#define PIPE_PRIM_TRIANGLE_FAN 6
#define PIPE_PRIM_QUADS 7
#define PIPE_PRIM_QUAD_STRIP 8
#define PIPE_PRIM_POLYGON 9
#define PIPE_PRIM_LINES_ADJACENCY 10
#define PIPE_PRIM_LINE_STRIP_ADJACENCY 11
#define PIPE_PRIM_TRIANGLES_ADJACENCY 12
#define PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY 13
#define PIPE_PRIM_MAX 14
/**
@ -393,6 +398,7 @@ enum pipe_transfer_usage {
#define PIPE_CAP_MAX_PREDICATE_REGISTERS 30
#define PIPE_CAP_MAX_COMBINED_SAMPLERS 31 /*< Maximum texture image units accessible from vertex
and fragment shaders combined */
#define PIPE_CAP_GEOMETRY_SHADER4 32
/**

View file

@ -121,16 +121,18 @@ struct tgsi_declaration_range
unsigned Last : 16; /**< UINT */
};
#define TGSI_SEMANTIC_POSITION 0
#define TGSI_SEMANTIC_COLOR 1
#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */
#define TGSI_SEMANTIC_FOG 3
#define TGSI_SEMANTIC_PSIZE 4
#define TGSI_SEMANTIC_GENERIC 5
#define TGSI_SEMANTIC_NORMAL 6
#define TGSI_SEMANTIC_FACE 7
#define TGSI_SEMANTIC_EDGEFLAG 8
#define TGSI_SEMANTIC_COUNT 9 /**< number of semantic values */
#define TGSI_SEMANTIC_POSITION 0
#define TGSI_SEMANTIC_COLOR 1
#define TGSI_SEMANTIC_BCOLOR 2 /**< back-face color */
#define TGSI_SEMANTIC_FOG 3
#define TGSI_SEMANTIC_PSIZE 4
#define TGSI_SEMANTIC_GENERIC 5
#define TGSI_SEMANTIC_NORMAL 6
#define TGSI_SEMANTIC_FACE 7
#define TGSI_SEMANTIC_EDGEFLAG 8
#define TGSI_SEMANTIC_VERTICES 9
#define TGSI_SEMANTIC_PRIMID 10
#define TGSI_SEMANTIC_COUNT 11 /**< number of semantic values */
struct tgsi_declaration_semantic
{

View file

@ -103,6 +103,25 @@ struct st_context {
$self->vs = vs;
}
void set_geometry_shader( const struct pipe_shader_state *state ) {
void *gs;
if(!state) {
cso_set_geometry_shader_handle($self->cso, NULL);
return;
}
gs = $self->pipe->create_gs_state($self->pipe, state);
if(!gs)
return;
if(cso_set_geometry_shader_handle($self->cso, gs) != PIPE_OK)
return;
cso_delete_geometry_shader($self->cso, $self->gs);
$self->gs = gs;
}
/*
* Parameter-like state (or properties)
*/

View file

@ -0,0 +1,254 @@
#!/usr/bin/env python
##########################################################################
#
# Copyright 2009 VMware
# 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.
#
##########################################################################
from gallium import *
def make_image(surface):
data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
import Image
outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
return outimage
def save_image(filename, surface):
outimage = make_image(surface)
outimage.save(filename, "PNG")
def show_image(surface):
outimage = make_image(surface)
import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()
root.title('background image')
image1 = ImageTk.PhotoImage(outimage)
w = image1.width()
h = image1.height()
x = 100
y = 100
root.geometry("%dx%d+%d+%d" % (w, h, x, y))
panel1 = tk.Label(root, image=image1)
panel1.pack(side='top', fill='both', expand='yes')
panel1.image = image1
root.mainloop()
def test(dev):
ctx = dev.context_create()
width = 255
height = 255
minz = 0.0
maxz = 1.0
# disabled blending/masking
blend = Blend()
blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE
blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE
blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
blend.colormask = PIPE_MASK_RGBA
ctx.set_blend(blend)
# depth/stencil/alpha
depth_stencil_alpha = DepthStencilAlpha()
depth_stencil_alpha.depth.enabled = 1
depth_stencil_alpha.depth.writemask = 1
depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
ctx.set_depth_stencil_alpha(depth_stencil_alpha)
# rasterizer
rasterizer = Rasterizer()
rasterizer.front_winding = PIPE_WINDING_CW
rasterizer.cull_mode = PIPE_WINDING_NONE
rasterizer.scissor = 1
ctx.set_rasterizer(rasterizer)
# viewport
viewport = Viewport()
scale = FloatArray(4)
scale[0] = width / 2.0
scale[1] = -height / 2.0
scale[2] = (maxz - minz) / 2.0
scale[3] = 1.0
viewport.scale = scale
translate = FloatArray(4)
translate[0] = width / 2.0
translate[1] = height / 2.0
translate[2] = (maxz - minz) / 2.0
translate[3] = 0.0
viewport.translate = translate
ctx.set_viewport(viewport)
# samplers
sampler = Sampler()
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
sampler.normalized_coords = 1
ctx.set_sampler(0, sampler)
# scissor
scissor = Scissor()
scissor.minx = 0
scissor.miny = 0
scissor.maxx = width
scissor.maxy = height
ctx.set_scissor(scissor)
clip = Clip()
clip.nr = 0
ctx.set_clip(clip)
# framebuffer
cbuf = dev.texture_create(
PIPE_FORMAT_X8R8G8B8_UNORM,
width, height,
tex_usage=PIPE_TEXTURE_USAGE_DISPLAY_TARGET,
).get_surface()
zbuf = dev.texture_create(
PIPE_FORMAT_Z16_UNORM,
width, height,
tex_usage=PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
).get_surface()
fb = Framebuffer()
fb.width = width
fb.height = height
fb.nr_cbufs = 1
fb.set_cbuf(0, cbuf)
fb.set_zsbuf(zbuf)
ctx.set_framebuffer(fb)
rgba = FloatArray(4);
rgba[0] = 0.0
rgba[1] = 0.0
rgba[2] = 0.0
rgba[3] = 0.0
ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
# vertex shader
vs = Shader('''
VERT
DCL IN[0], POSITION, CONSTANT
DCL IN[1], COLOR, CONSTANT
DCL OUT[0], POSITION, CONSTANT
DCL OUT[1], COLOR, CONSTANT
0:MOV OUT[0], IN[0]
1:MOV OUT[1], IN[1]
2:END
''')
ctx.set_vertex_shader(vs)
gs = Shader('''
GEOM
PROPERTY GS_INPUT_PRIMITIVE TRIANGLES
PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP
DCL IN[][0], POSITION, CONSTANT
DCL IN[][1], COLOR, CONSTANT
DCL OUT[0], POSITION, CONSTANT
DCL OUT[1], COLOR, CONSTANT
0:MOV OUT[0], IN[0][0]
1:MOV OUT[1], IN[0][1]
2:EMIT_VERTEX
3:MOV OUT[0], IN[1][0]
4:MOV OUT[1], IN[1][1]
5:EMIT_VERTEX
6:MOV OUT[0], IN[2][0]
7:MOV OUT[1], IN[2][1]
8:EMIT_VERTEX
9:END_PRIMITIVE
10:END
''')
ctx.set_geometry_shader(gs)
# fragment shader
fs = Shader('''
FRAG
DCL IN[0], COLOR, LINEAR
DCL OUT[0], COLOR, CONSTANT
0:MOV OUT[0], IN[0]
1:END
''')
ctx.set_fragment_shader(fs)
nverts = 3
nattrs = 2
verts = FloatArray(nverts * nattrs * 4)
verts[ 0] = 0.0 # x1
verts[ 1] = 0.8 # y1
verts[ 2] = 0.2 # z1
verts[ 3] = 1.0 # w1
verts[ 4] = 1.0 # r1
verts[ 5] = 0.0 # g1
verts[ 6] = 0.0 # b1
verts[ 7] = 1.0 # a1
verts[ 8] = -0.8 # x2
verts[ 9] = -0.8 # y2
verts[10] = 0.5 # z2
verts[11] = 1.0 # w2
verts[12] = 0.0 # r2
verts[13] = 1.0 # g2
verts[14] = 0.0 # b2
verts[15] = 1.0 # a2
verts[16] = 0.8 # x3
verts[17] = -0.8 # y3
verts[18] = 0.8 # z3
verts[19] = 1.0 # w3
verts[20] = 0.0 # r3
verts[21] = 0.0 # g3
verts[22] = 1.0 # b3
verts[23] = 1.0 # a3
ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
nverts,
nattrs,
verts)
ctx.flush()
show_image(cbuf)
#show_image(zbuf)
#save_image('cbuf.png', cbuf)
#save_image('zbuf.png', zbuf)
def main():
dev = Device()
test(dev)
if __name__ == '__main__':
main()

View file

@ -57,6 +57,7 @@ struct st_context {
void *vs;
void *fs;
void *gs;
struct pipe_texture *default_texture;
struct pipe_texture *sampler_textures[PIPE_MAX_SAMPLERS];

View file

@ -241,7 +241,8 @@ st_feedback_draw_vbo(GLcontext *ctx,
mapped_constants = pipe_buffer_map(pipe->screen,
st->state.constants[PIPE_SHADER_VERTEX].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_constant_buffer(st->draw, mapped_constants,
draw_set_mapped_constant_buffer(st->draw, PIPE_SHADER_VERTEX,
mapped_constants,
st->state.constants[PIPE_SHADER_VERTEX].buffer->size);