summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r600/r600_render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/r600/r600_render.c')
-rw-r--r--src/mesa/drivers/dri/r600/r600_render.c539
1 files changed, 0 insertions, 539 deletions
diff --git a/src/mesa/drivers/dri/r600/r600_render.c b/src/mesa/drivers/dri/r600/r600_render.c
deleted file mode 100644
index 7b4ecccc66..0000000000
--- a/src/mesa/drivers/dri/r600/r600_render.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/**************************************************************************
-
-Copyright (C) 2004 Nicolai Haehnle.
-
-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
-on 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
-ATI, VA LINUX SYSTEMS AND/OR THEIR 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.
-
-**************************************************************************/
-
-/**
- * \file
- *
- * \brief R600 Render (Vertex Buffer Implementation)
- *
- * The immediate implementation has been removed from CVS in favor of the vertex
- * buffer implementation.
- *
- * The render functions are called by the pipeline manager to render a batch of
- * primitives. They return TRUE to pass on to the next stage (i.e. software
- * rasterization) or FALSE to indicate that the pipeline has finished after
- * rendering something.
- *
- * When falling back to software TCL still attempt to use hardware
- * rasterization.
- *
- * I am not sure that the cache related registers are setup correctly, but
- * obviously this does work... Further investigation is needed.
- *
- * \author Nicolai Haehnle <prefect_@gmx.net>
- *
- * \todo Add immediate implementation back? Perhaps this is useful if there are
- * no bugs...
- */
-
-#include "main/glheader.h"
-#include "main/state.h"
-#include "main/imports.h"
-#include "main/enums.h"
-#include "main/macros.h"
-#include "main/context.h"
-#include "main/dd.h"
-#include "main/simple_list.h"
-#include "main/api_arrayelt.h"
-#include "swrast/swrast.h"
-#include "swrast_setup/swrast_setup.h"
-#include "vbo/vbo.h"
-#include "tnl/tnl.h"
-#include "tnl/t_vp_build.h"
-#include "radeon_reg.h"
-#include "radeon_macros.h"
-#include "r600_context.h"
-#include "r600_ioctl.h"
-#include "r600_state.h"
-#include "r600_reg.h"
-#include "r600_tex.h"
-#include "r600_emit.h"
-#include "r600_fragprog.h"
-extern int future_hw_tcl_on;
-
-/**
- * \brief Convert a OpenGL primitive type into a R600 primitive type.
- */
-int r600PrimitiveType(r600ContextPtr rmesa, int prim)
-{
- switch (prim & PRIM_MODE_MASK) {
- case GL_POINTS:
- return R600_VAP_VF_CNTL__PRIM_POINTS;
- break;
- case GL_LINES:
- return R600_VAP_VF_CNTL__PRIM_LINES;
- break;
- case GL_LINE_STRIP:
- return R600_VAP_VF_CNTL__PRIM_LINE_STRIP;
- break;
- case GL_LINE_LOOP:
- return R600_VAP_VF_CNTL__PRIM_LINE_LOOP;
- break;
- case GL_TRIANGLES:
- return R600_VAP_VF_CNTL__PRIM_TRIANGLES;
- break;
- case GL_TRIANGLE_STRIP:
- return R600_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
- break;
- case GL_TRIANGLE_FAN:
- return R600_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
- break;
- case GL_QUADS:
- return R600_VAP_VF_CNTL__PRIM_QUADS;
- break;
- case GL_QUAD_STRIP:
- return R600_VAP_VF_CNTL__PRIM_QUAD_STRIP;
- break;
- case GL_POLYGON:
- return R600_VAP_VF_CNTL__PRIM_POLYGON;
- break;
- default:
- assert(0);
- return -1;
- break;
- }
-}
-
-int r600NumVerts(r600ContextPtr rmesa, int num_verts, int prim)
-{
- int verts_off = 0;
-
- switch (prim & PRIM_MODE_MASK) {
- case GL_POINTS:
- verts_off = 0;
- break;
- case GL_LINES:
- verts_off = num_verts % 2;
- break;
- case GL_LINE_STRIP:
- if (num_verts < 2)
- verts_off = num_verts;
- break;
- case GL_LINE_LOOP:
- if (num_verts < 2)
- verts_off = num_verts;
- break;
- case GL_TRIANGLES:
- verts_off = num_verts % 3;
- break;
- case GL_TRIANGLE_STRIP:
- if (num_verts < 3)
- verts_off = num_verts;
- break;
- case GL_TRIANGLE_FAN:
- if (num_verts < 3)
- verts_off = num_verts;
- break;
- case GL_QUADS:
- verts_off = num_verts % 4;
- break;
- case GL_QUAD_STRIP:
- if (num_verts < 4)
- verts_off = num_verts;
- else
- verts_off = num_verts % 2;
- break;
- case GL_POLYGON:
- if (num_verts < 3)
- verts_off = num_verts;
- break;
- default:
- assert(0);
- return -1;
- break;
- }
-
- return num_verts - verts_off;
-}
-
-static void r600EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts)
-{
- r600ContextPtr rmesa = R600_CONTEXT(ctx);
- void *out;
-
- radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
- &rmesa->radeon.tcl.elt_dma_offset, n_elts * 4, 4);
- radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
- out = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
- memcpy(out, elts, n_elts * 4);
- radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);
-}
-
-static void r600FireEB(r600ContextPtr rmesa, int vertex_count, int type)
-{
- BATCH_LOCALS(&rmesa->radeon);
-
- if (vertex_count > 0) {
- BEGIN_BATCH(10);
- OUT_BATCH_PACKET3(R600_PACKET3_3D_DRAW_INDX_2, 0);
- OUT_BATCH(R600_VAP_VF_CNTL__PRIM_WALK_INDICES |
- ((vertex_count + 0) << 16) |
- type |
- R600_VAP_VF_CNTL__INDEX_SIZE_32bit);
-
- if (!rmesa->radeon.radeonScreen->kernel_mm) {
- OUT_BATCH_PACKET3(R600_PACKET3_INDX_BUFFER, 2);
- OUT_BATCH(R600_INDX_BUFFER_ONE_REG_WR | (0 << R600_INDX_BUFFER_SKIP_SHIFT) |
- (R600_VAP_PORT_IDX0 >> 2));
- OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset,
- rmesa->radeon.tcl.elt_dma_bo,
- rmesa->radeon.tcl.elt_dma_offset,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- OUT_BATCH(vertex_count);
- } else {
- OUT_BATCH_PACKET3(R600_PACKET3_INDX_BUFFER, 2);
- OUT_BATCH(R600_INDX_BUFFER_ONE_REG_WR | (0 << R600_INDX_BUFFER_SKIP_SHIFT) |
- (R600_VAP_PORT_IDX0 >> 2));
- OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset);
- OUT_BATCH(vertex_count);
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->radeon.tcl.elt_dma_bo,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- }
- END_BATCH();
- }
-}
-
-static void r600EmitAOS(r600ContextPtr rmesa, GLuint nr, GLuint offset)
-{
- BATCH_LOCALS(&rmesa->radeon);
- uint32_t voffset;
- int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
- int i;
-
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
- offset);
-
-
- if (!rmesa->radeon.radeonScreen->kernel_mm) {
- BEGIN_BATCH(sz+2+(nr * 2));
- OUT_BATCH_PACKET3(R600_PACKET3_3D_LOAD_VBPNTR, sz - 1);
- OUT_BATCH(nr);
-
- for (i = 0; i + 1 < nr; i += 2) {
- OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
- (rmesa->radeon.tcl.aos[i].stride << 8) |
- (rmesa->radeon.tcl.aos[i + 1].components << 16) |
- (rmesa->radeon.tcl.aos[i + 1].stride << 24));
-
- voffset = rmesa->radeon.tcl.aos[i + 0].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
- OUT_BATCH_RELOC(voffset,
- rmesa->radeon.tcl.aos[i].bo,
- voffset,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- voffset = rmesa->radeon.tcl.aos[i + 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
- OUT_BATCH_RELOC(voffset,
- rmesa->radeon.tcl.aos[i+1].bo,
- voffset,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- }
-
- if (nr & 1) {
- OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
- (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
- voffset = rmesa->radeon.tcl.aos[nr - 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
- OUT_BATCH_RELOC(voffset,
- rmesa->radeon.tcl.aos[nr - 1].bo,
- voffset,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- }
- END_BATCH();
- } else {
-
- BEGIN_BATCH(sz+2+(nr * 2));
- OUT_BATCH_PACKET3(R600_PACKET3_3D_LOAD_VBPNTR, sz - 1);
- OUT_BATCH(nr);
-
- for (i = 0; i + 1 < nr; i += 2) {
- OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) |
- (rmesa->radeon.tcl.aos[i].stride << 8) |
- (rmesa->radeon.tcl.aos[i + 1].components << 16) |
- (rmesa->radeon.tcl.aos[i + 1].stride << 24));
-
- voffset = rmesa->radeon.tcl.aos[i + 0].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
- OUT_BATCH(voffset);
- voffset = rmesa->radeon.tcl.aos[i + 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
- OUT_BATCH(voffset);
- }
-
- if (nr & 1) {
- OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) |
- (rmesa->radeon.tcl.aos[nr - 1].stride << 8));
- voffset = rmesa->radeon.tcl.aos[nr - 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
- OUT_BATCH(voffset);
- }
- for (i = 0; i + 1 < nr; i += 2) {
- voffset = rmesa->radeon.tcl.aos[i + 0].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride;
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->radeon.tcl.aos[i+0].bo,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- voffset = rmesa->radeon.tcl.aos[i + 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride;
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->radeon.tcl.aos[i+1].bo,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- }
- if (nr & 1) {
- voffset = rmesa->radeon.tcl.aos[nr - 1].offset +
- offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride;
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->radeon.tcl.aos[nr-1].bo,
- RADEON_GEM_DOMAIN_GTT,
- 0, 0);
- }
- END_BATCH();
- }
-
-}
-
-static void r600FireAOS(r600ContextPtr rmesa, int vertex_count, int type)
-{
- BATCH_LOCALS(&rmesa->radeon);
-
- BEGIN_BATCH(3);
- OUT_BATCH_PACKET3(R600_PACKET3_3D_DRAW_VBUF_2, 0);
- OUT_BATCH(R600_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
- END_BATCH();
-}
-
-static void r600RunRenderPrimitive(r600ContextPtr rmesa, GLcontext * ctx,
- int start, int end, int prim)
-{
- int type, num_verts;
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *vb = &tnl->vb;
-
- type = r600PrimitiveType(rmesa, prim);
- num_verts = r600NumVerts(rmesa, end - start, prim);
-
- if (type < 0 || num_verts <= 0)
- return;
-
- /* Make space for at least 64 dwords.
- * This is supposed to ensure that we can get all rendering
- * commands into a single command buffer.
- */
- rcommonEnsureCmdBufSpace(&rmesa->radeon, 64, __FUNCTION__);
-
- if (vb->Elts) {
- if (num_verts > 65535) {
- /* not implemented yet */
- WARN_ONCE("Too many elts\n");
- return;
- }
- /* Note: The following is incorrect, but it's the best I can do
- * without a major refactoring of how DMA memory is handled.
- * The problem: Ensuring that both vertex arrays *and* index
- * arrays are at the right position, and then ensuring that
- * the LOAD_VBPNTR, DRAW_INDX and INDX_BUFFER packets are emitted
- * at once.
- *
- * So why is the following incorrect? Well, it seems like
- * allocating the index array might actually evict the vertex
- * arrays. *sigh*
- */
- r600EmitElts(ctx, vb->Elts, num_verts);
- r600EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start);
- r600FireEB(rmesa, num_verts, type);
- } else {
- r600EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start);
- r600FireAOS(rmesa, num_verts, type);
- }
- COMMIT_BATCH();
-}
-
-static GLboolean r600RunRender(GLcontext * ctx,
- struct tnl_pipeline_stage *stage)
-{
- r600ContextPtr rmesa = R600_CONTEXT(ctx);
- int i;
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *vb = &tnl->vb;
-
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- r600UpdateShaders(rmesa);
- if (r600EmitArrays(ctx))
- return GL_TRUE;
-
- r600UpdateShaderStates(rmesa);
-
- r600EmitCacheFlush(rmesa);
- radeonEmitState(&rmesa->radeon);
-
- for (i = 0; i < vb->PrimitiveCount; i++) {
- GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
- GLuint start = vb->Primitive[i].start;
- GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
- r600RunRenderPrimitive(rmesa, ctx, start, end, prim);
- }
-
- r600EmitCacheFlush(rmesa);
-
- radeonReleaseArrays(ctx, ~0);
-
- return GL_FALSE;
-}
-
-#define FALLBACK_IF(expr) \
- do { \
- if (expr) { \
- if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
- WARN_ONCE("Software fallback:%s\n", \
- #expr); \
- return R600_FALLBACK_RAST; \
- } \
- } while(0)
-
-static int r600Fallback(GLcontext * ctx)
-{
- r600ContextPtr r600 = R600_CONTEXT(ctx);
- const unsigned back = ctx->Stencil._BackFace;
-
- FALLBACK_IF(r600->radeon.Fallback);
- /* Do we need to use new-style shaders?
- * Also is there a better way to do this? */
- {
- struct r600_fragment_program *fp = (struct r600_fragment_program *)
- (char *)ctx->FragmentProgram._Current;
- if (fp) {
- if (!fp->translated) {
- r600TranslateFragmentShader(r600, fp);
- FALLBACK_IF(!fp->translated);
- }
- }
- }
-
- FALLBACK_IF(ctx->RenderMode != GL_RENDER);
-
- /* If GL_EXT_stencil_two_side is disabled, this fallback check can
- * be removed.
- */
- FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
- || ctx->Stencil.ValueMask[0] !=
- ctx->Stencil.ValueMask[back]
- || ctx->Stencil.WriteMask[0] !=
- ctx->Stencil.WriteMask[back]);
-
- if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
- FALLBACK_IF(ctx->Point.PointSprite);
-
- if (!r600->disable_lowimpact_fallback) {
- FALLBACK_IF(ctx->Polygon.StippleFlag);
- FALLBACK_IF(ctx->Multisample._Enabled);
- FALLBACK_IF(ctx->Line.StippleFlag);
- FALLBACK_IF(ctx->Line.SmoothFlag);
- FALLBACK_IF(ctx->Point.SmoothFlag);
- }
-
- return R600_FALLBACK_NONE;
-}
-
-static GLboolean r600RunNonTCLRender(GLcontext * ctx,
- struct tnl_pipeline_stage *stage)
-{
- r600ContextPtr rmesa = R600_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (r600Fallback(ctx) >= R600_FALLBACK_RAST)
- return GL_TRUE;
-
- if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
- return GL_TRUE;
-
- if (!r600ValidateBuffers(ctx))
- return GL_TRUE;
-
- return r600RunRender(ctx, stage);
-}
-
-static GLboolean r600RunTCLRender(GLcontext * ctx,
- struct tnl_pipeline_stage *stage)
-{
- r600ContextPtr rmesa = R600_CONTEXT(ctx);
- struct r600_vertex_program *vp;
-
- hw_tcl_on = future_hw_tcl_on;
-
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (hw_tcl_on == GL_FALSE)
- return GL_TRUE;
-
- if (r600Fallback(ctx) >= R600_FALLBACK_TCL) {
- hw_tcl_on = GL_FALSE;
- return GL_TRUE;
- }
-
- if (!r600ValidateBuffers(ctx))
- return GL_TRUE;
-
- r600UpdateShaders(rmesa);
-
- vp = (struct r600_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
- if (vp->native == GL_FALSE) {
- hw_tcl_on = GL_FALSE;
- return GL_TRUE;
- }
-
- return r600RunRender(ctx, stage);
-}
-
-const struct tnl_pipeline_stage _r600_render_stage = {
- "r600 Hardware Rasterization",
- NULL,
- NULL,
- NULL,
- NULL,
- r600RunNonTCLRender
-};
-
-const struct tnl_pipeline_stage _r600_tcl_stage = {
- "r600 Hardware Transform, Clipping and Lighting",
- NULL,
- NULL,
- NULL,
- NULL,
- r600RunTCLRender
-};