*/
-#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
-#include "tgsi/util/tgsi_transform.h"
-#include "tgsi/util/tgsi_dump.h"
+#include "tgsi/tgsi_transform.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
#include "draw_context.h"
#include "draw_vs.h"
+#include "draw_pipe.h"
/*
/** this is the vertex attrib slot for the new texcoords */
uint tex_slot;
+ uint pos_slot;
/*
* Currently bound state
if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
decl->Semantic.SemanticIndex == 0) {
- aactx->colorOutput = decl->u.DeclarationRange.First;
+ aactx->colorOutput = decl->DeclarationRange.First;
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
- if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
- aactx->maxInput = decl->u.DeclarationRange.Last;
+ if ((int) decl->DeclarationRange.Last > aactx->maxInput)
+ aactx->maxInput = decl->DeclarationRange.Last;
if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
(int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
aactx->maxGeneric = decl->Semantic.SemanticIndex;
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
uint i;
- for (i = decl->u.DeclarationRange.First;
- i <= decl->u.DeclarationRange.Last; i++) {
+ for (i = decl->DeclarationRange.First;
+ i <= decl->DeclarationRange.Last; i++) {
aactx->tempsUsed |= (1 << i);
}
}
/* declare new generic input/texcoord */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
+ /* XXX this could be linear... */
+ decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
decl.Declaration.Semantic = 1;
decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
- decl.Declaration.Interpolate = 1;
- /* XXX this could be linear... */
- decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = texInput;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = texInput;
ctx->emit_declaration(ctx, &decl);
/* declare new temp regs */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = tmp0;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = tmp0;
ctx->emit_declaration(ctx, &decl);
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.u.DeclarationRange.First =
- decl.u.DeclarationRange.Last = aactx->colorTemp;
+ decl.DeclarationRange.First =
+ decl.DeclarationRange.Last = aactx->colorTemp;
ctx->emit_declaration(ctx, &decl);
aactx->firstInstruction = FALSE;
newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
ctx->emit_instruction(ctx, &newInst);
- /* KILP -t0.yyyy; # if b, KILL */
+ /* KIL -tmp0.yyyy; # if -tmp0.y < 0, KILL */
newInst = tgsi_default_full_instruction();
- newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
+ newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
newInst.Instruction.NumDstRegs = 0;
newInst.Instruction.NumSrcRegs = 1;
newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
/**
- * Generate the frag shader we'll use for drawing AA lines.
+ * Generate the frag shader we'll use for drawing AA points.
* This will be the user's shader plus some texture/modulate instructions.
*/
-static void
+static boolean
generate_aapoint_fs(struct aapoint_stage *aapoint)
{
const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
aapoint_fs = *orig_fs; /* copy to init */
aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
+ if (aapoint_fs.tokens == NULL)
+ return FALSE;
memset(&transform, 0, sizeof(transform));
transform.colorOutput = -1;
aapoint->fs->aapoint_fs
= aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+ if (aapoint->fs->aapoint_fs == NULL)
+ return FALSE;
aapoint->fs->generic_attrib = transform.maxGeneric + 1;
+
+ return TRUE;
}
/**
- * When we're about to draw our first AA line in a batch, this function is
+ * When we're about to draw our first AA point in a batch, this function is
* called to tell the driver to bind our modified fragment shader.
*/
-static void
+static boolean
bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
{
- if (!aapoint->fs->aapoint_fs) {
- generate_aapoint_fs(aapoint);
- }
+ struct draw_context *draw = aapoint->stage.draw;
+
+ if (!aapoint->fs->aapoint_fs &&
+ !generate_aapoint_fs(aapoint))
+ return FALSE;
+
+ draw->suspend_flushing = TRUE;
aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+ draw->suspend_flushing = FALSE;
+
+ return TRUE;
}
}
-static void
-passthrough_line(struct draw_stage *stage, struct prim_header *header)
-{
- stage->next->line(stage->next, header);
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
- stage->next->tri(stage->next, header);
-}
/**
struct prim_header tri;
struct vertex_header *v[4];
uint texPos = aapoint->tex_slot;
+ uint pos_slot = aapoint->pos_slot;
float radius, *pos, *tex;
uint i;
float k;
}
/* new verts */
- pos = v[0]->data[0];
+ pos = v[0]->data[pos_slot];
pos[0] -= radius;
pos[1] -= radius;
- pos = v[1]->data[0];
+ pos = v[1]->data[pos_slot];
pos[0] += radius;
pos[1] -= radius;
- pos = v[2]->data[0];
+ pos = v[2]->data[pos_slot];
pos[0] += radius;
pos[1] += radius;
- pos = v[3]->data[0];
+ pos = v[3]->data[pos_slot];
pos[0] -= radius;
pos[1] += radius;
bind_aapoint_fragment_shader(aapoint);
/* update vertex attrib info */
- aapoint->tex_slot = draw->num_vs_outputs;
+ aapoint->tex_slot = draw->vs.num_vs_outputs;
assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
+ aapoint->pos_slot = draw->vs.position_output;
+
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;
aapoint->psize_slot = -1;
if (draw->rasterizer->point_size_per_vertex) {
/* find PSIZ vertex output */
- const struct draw_vertex_shader *vs = draw->vertex_shader;
+ const struct draw_vertex_shader *vs = draw->vs.vertex_shader;
uint i;
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
}
}
- /* now really draw first line */
+ /* now really draw first point */
stage->point = aapoint_point;
stage->point(stage, header);
}
stage->next->flush( stage->next, flags );
/* restore original frag shader */
+ draw->suspend_flushing = TRUE;
aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
+ draw->suspend_flushing = FALSE;
draw->extra_vp_outputs.slot = 0;
}
draw_aapoint_stage(struct draw_context *draw)
{
struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
+ if (aapoint == NULL)
+ goto fail;
- draw_alloc_temp_verts( &aapoint->stage, 4 );
+ if (!draw_alloc_temp_verts( &aapoint->stage, 4 ))
+ goto fail;
aapoint->stage.draw = draw;
aapoint->stage.next = NULL;
aapoint->stage.point = aapoint_first_point;
- aapoint->stage.line = passthrough_line;
- aapoint->stage.tri = passthrough_tri;
+ aapoint->stage.line = draw_pipe_passthrough_line;
+ aapoint->stage.tri = draw_pipe_passthrough_tri;
aapoint->stage.flush = aapoint_flush;
aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
aapoint->stage.destroy = aapoint_destroy;
return aapoint;
+
+ fail:
+ if (aapoint)
+ aapoint_destroy(&aapoint->stage);
+
+ return NULL;
+
}
{
struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
+ if (aafs == NULL)
+ return NULL;
- if (aafs) {
- aafs->state = *fs;
+ aafs->state = *fs;
- /* pass-through */
- aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
- }
+ /* pass-through */
+ aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
return aafs;
}
* into the draw module's pipeline. This will not be used if the
* hardware has native support for AA points.
*/
-void
+boolean
draw_install_aapoint_stage(struct draw_context *draw,
struct pipe_context *pipe)
{
* Create / install AA point drawing / prim stage
*/
aapoint = draw_aapoint_stage( draw );
- assert(aapoint);
- draw->pipeline.aapoint = &aapoint->stage;
+ if (aapoint == NULL)
+ goto fail;
aapoint->pipe = pipe;
pipe->create_fs_state = aapoint_create_fs_state;
pipe->bind_fs_state = aapoint_bind_fs_state;
pipe->delete_fs_state = aapoint_delete_fs_state;
+
+ draw->pipeline.aapoint = &aapoint->stage;
+
+ return TRUE;
+
+ fail:
+ if (aapoint)
+ aapoint->stage.destroy( &aapoint->stage );
+
+ return FALSE;
}