mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 16:48:07 +02:00
gallium: add geometry shader support to gallium
This commit is contained in:
parent
57cce7a409
commit
89d8577fb3
54 changed files with 1159 additions and 137 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
338
src/gallium/auxiliary/draw/draw_gs.c
Normal file
338
src/gallium/auxiliary/draw/draw_gs.c
Normal 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);
|
||||
}
|
||||
}
|
||||
76
src/gallium/auxiliary/draw/draw_gs.h
Normal file
76
src/gallium/auxiliary/draw/draw_gs.h
Normal 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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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__);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -122,7 +122,9 @@ static const char *semantic_names[] =
|
|||
"GENERIC",
|
||||
"NORMAL",
|
||||
"FACE",
|
||||
"EDGEFLAG"
|
||||
"EDGEFLAG",
|
||||
"VERTICES_IN",
|
||||
"PRIM_ID"
|
||||
};
|
||||
|
||||
static const char *immediate_type_names[] =
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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] =
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
||||
|
|
|
|||
|
|
@ -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 * );
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *);
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
|||
254
src/gallium/state_trackers/python/samples/gs.py
Normal file
254
src/gallium/state_trackers/python/samples/gs.py
Normal 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()
|
||||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue