summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r600
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2012-08-24 05:57:22 +0200
committerMarek Olšák <[email protected]>2012-08-30 19:43:55 +0200
commit187d7fb2fec7da889f25366696faaac4c2e8f9c4 (patch)
treebd46f0a9e4fdb3309bc4b2e043b76d4db3a141af /src/gallium/drivers/r600
parent8698a3b85dd89c5d2fa473e7942b7dc8d25f3c8f (diff)
r600g: implement draw_rectangle callback
The color resolve on r6xx needs PT_RECTLIST. Using conventional primitive types (triangles and quads) produces an ugly line between two diagonally opposite corners. I guess a rectangular point sprite would work too.
Diffstat (limited to 'src/gallium/drivers/r600')
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h4
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c69
3 files changed, 72 insertions, 2 deletions
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 34ba80b244f..77adeaef8bc 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -294,6 +294,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
rctx->blitter = util_blitter_create(&rctx->context);
if (rctx->blitter == NULL)
goto fail;
+ rctx->blitter->draw_rectangle = r600_draw_rectangle;
r600_get_backend_mask(rctx); /* this emits commands and must be last */
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 074eed432dc..9cbf0c88e64 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -26,6 +26,7 @@
#ifndef R600_PIPE_H
#define R600_PIPE_H
+#include "util/u_blitter.h"
#include "util/u_slab.h"
#include "r600.h"
#include "r600_llvm.h"
@@ -638,6 +639,9 @@ void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask);
void r600_set_pipe_stencil_ref(struct pipe_context *ctx,
const struct pipe_stencil_ref *state);
void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info);
+void r600_draw_rectangle(struct blitter_context *blitter,
+ unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth,
+ enum blitter_attrib_type type, const union pipe_color_union *attrib);
uint32_t r600_translate_stencil_op(int s_op);
uint32_t r600_translate_fill(uint32_t func);
unsigned r600_tex_wrap(unsigned wrap);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 77c3e20599e..e8801329d3f 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -27,11 +27,13 @@
#include "r600_formats.h"
#include "r600d.h"
-#include "util/u_blitter.h"
+#include "util/u_draw_quad.h"
#include "util/u_upload_mgr.h"
#include "tgsi/tgsi_parse.h"
#include <byteswap.h>
+#define R600_PRIM_RECTANGLE_LIST PIPE_PRIM_MAX
+
static void r600_emit_command_buffer(struct r600_context *rctx, struct r600_atom *atom)
{
struct radeon_winsys_cs *cs = rctx->cs;
@@ -153,7 +155,8 @@ static bool r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
-1,
-1,
-1,
- -1
+ -1,
+ V_008958_DI_PT_RECTLIST
};
*prim = prim_conv[pprim];
@@ -1110,6 +1113,7 @@ static unsigned r600_conv_prim_to_gs_out(unsigned mode)
V_028A6C_OUTPRIM_TYPE_LINESTRIP,
V_028A6C_OUTPRIM_TYPE_LINESTRIP,
V_028A6C_OUTPRIM_TYPE_TRISTRIP,
+ V_028A6C_OUTPRIM_TYPE_TRISTRIP,
V_028A6C_OUTPRIM_TYPE_TRISTRIP
};
assert(mode < Elements(prim_conv));
@@ -1293,6 +1297,67 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
pipe_resource_reference(&ib.buffer, NULL);
}
+void r600_draw_rectangle(struct blitter_context *blitter,
+ unsigned x1, unsigned y1, unsigned x2, unsigned y2, float depth,
+ enum blitter_attrib_type type, const union pipe_color_union *attrib)
+{
+ struct r600_context *rctx = (struct r600_context*)util_blitter_get_pipe(blitter);
+ struct pipe_viewport_state viewport;
+ struct pipe_resource *buf = NULL;
+ unsigned offset = 0;
+ float *vb;
+
+ if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
+ util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib);
+ return;
+ }
+
+ /* Some operations (like color resolve on r6xx) don't work
+ * with the conventional primitive types.
+ * One that works is PT_RECTLIST, which we use here. */
+
+ /* setup viewport */
+ viewport.scale[0] = 1.0f;
+ viewport.scale[1] = 1.0f;
+ viewport.scale[2] = 1.0f;
+ viewport.scale[3] = 1.0f;
+ viewport.translate[0] = 0.0f;
+ viewport.translate[1] = 0.0f;
+ viewport.translate[2] = 0.0f;
+ viewport.translate[3] = 0.0f;
+ rctx->context.set_viewport_state(&rctx->context, &viewport);
+
+ /* Upload vertices. The hw rectangle has only 3 vertices,
+ * I guess the 4th one is derived from the first 3.
+ * The vertex specification should match u_blitter's vertex element state. */
+ u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, &offset, &buf, (void**)&vb);
+ vb[0] = x1;
+ vb[1] = y1;
+ vb[2] = depth;
+ vb[3] = 1;
+
+ vb[8] = x1;
+ vb[9] = y2;
+ vb[10] = depth;
+ vb[11] = 1;
+
+ vb[16] = x2;
+ vb[17] = y1;
+ vb[18] = depth;
+ vb[19] = 1;
+
+ if (attrib) {
+ memcpy(vb+4, attrib->f, sizeof(float)*4);
+ memcpy(vb+12, attrib->f, sizeof(float)*4);
+ memcpy(vb+20, attrib->f, sizeof(float)*4);
+ }
+
+ /* draw */
+ util_draw_vertex_buffer(&rctx->context, NULL, buf, offset,
+ R600_PRIM_RECTANGLE_LIST, 3, 2);
+ pipe_resource_reference(&buf, NULL);
+}
+
void _r600_pipe_state_add_reg_bo(struct r600_context *ctx,
struct r600_pipe_state *state,
uint32_t offset, uint32_t value,