123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie/**************************************************************************
223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
323d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieCopyright (C) 2004 Nicolai Haehnle.
423d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieCopyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
623d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieThe Weather Channel (TM) funded Tungsten Graphics to develop the
723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlieinitial release of the Radeon 8500 driver under the XFree86 license.
823d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieThis notice must be preserved.
923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
1023d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieAll Rights Reserved.
1123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
1223d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirliePermission is hereby granted, free of charge, to any person obtaining a
1323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airliecopy of this software and associated documentation files (the "Software"),
1423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlieto deal in the Software without restriction, including without limitation
1523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlieon the rights to use, copy, modify, merge, publish, distribute, sub
1623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlielicense, and/or sell copies of the Software, and to permit persons to whom
1723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airliethe Software is furnished to do so, subject to the following conditions:
1823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
1923d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieThe above copyright notice and this permission notice (including the next
2023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlieparagraph) shall be included in all copies or substantial portions of the
2123d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieSoftware.
2223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
2323d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2423d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2523d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieFITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
2623d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
2723d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieDAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
2823d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2923d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirlieUSE OR OTHER DEALINGS IN THE SOFTWARE.
3023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
3123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie**************************************************************************/
3223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
3366bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen#include <errno.h>
3423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#include "radeon_common.h"
3594556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher#include "radeon_fog.h"
36bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen#include "main/simple_list.h"
3723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
3823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#if defined(USE_X86_ASM)
3923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#define COPY_DWORDS( dst, src, nr )					\
4023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airliedo {									\
4123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	int __tmp;							\
4223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	__asm__ __volatile__( "rep ; movsl"				\
4323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			      : "=%c" (__tmp), "=D" (dst), "=S" (__tmp)	\
4423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			      : "0" (nr),				\
4523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			        "D" ((long)dst),			\
4623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			        "S" ((long)src) );			\
4723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie} while (0)
4823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#else
4923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#define COPY_DWORDS( dst, src, nr )		\
5023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airliedo {						\
5123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie   int j;					\
5223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie   for ( j = 0 ; j < nr ; j++ )			\
5323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie      dst[j] = ((int *)src)[j];			\
5423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie   dst += nr;					\
5523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie} while (0)
5623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie#endif
5723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
582233ac61e1a690f47a7d4a9d0894c1c20c9c330fMaciej Cencoravoid radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count)
5923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
6023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	int i;
6123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
624e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_VERTS)
6323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		fprintf(stderr, "%s count %d stride %d out %p data %p\n",
6423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			__FUNCTION__, count, stride, (void *)out, (void *)data);
6523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
6623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (stride == 4)
6723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		COPY_DWORDS(out, data, count);
6823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	else
6923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		for (i = 0; i < count; i++) {
7023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[0] = *(int *)data;
7123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out++;
7223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			data += stride;
7323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		}
7423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
7523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
76d534648d904da71e604babcf408c00eae7922d16Maciej Cencoravoid radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count)
7723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
7823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	int i;
7923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
804e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_VERTS)
8123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		fprintf(stderr, "%s count %d stride %d out %p data %p\n",
8223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			__FUNCTION__, count, stride, (void *)out, (void *)data);
8323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
8423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (stride == 8)
8523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		COPY_DWORDS(out, data, count * 2);
8623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	else
8723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		for (i = 0; i < count; i++) {
8823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[0] = *(int *)data;
8923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[1] = *(int *)(data + 4);
9023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out += 2;
9123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			data += stride;
9223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		}
9323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
9423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
95d534648d904da71e604babcf408c00eae7922d16Maciej Cencoravoid radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count)
9623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
9723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	int i;
9823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
994e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_VERTS)
10023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		fprintf(stderr, "%s count %d stride %d out %p data %p\n",
10123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			__FUNCTION__, count, stride, (void *)out, (void *)data);
10223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
10323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (stride == 12) {
10423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		COPY_DWORDS(out, data, count * 3);
10523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie    }
10623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	else
10723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		for (i = 0; i < count; i++) {
10823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[0] = *(int *)data;
10923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[1] = *(int *)(data + 4);
11023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[2] = *(int *)(data + 8);
11123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out += 3;
11223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			data += stride;
11323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		}
11423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
11523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
1162233ac61e1a690f47a7d4a9d0894c1c20c9c330fMaciej Cencoravoid radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count)
11723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
11823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	int i;
11923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
1204e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_VERTS)
12123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		fprintf(stderr, "%s count %d stride %d out %p data %p\n",
12223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			__FUNCTION__, count, stride, (void *)out, (void *)data);
12323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
12423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (stride == 16)
12523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		COPY_DWORDS(out, data, count * 4);
12623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	else
12723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		for (i = 0; i < count; i++) {
12823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[0] = *(int *)data;
12923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[1] = *(int *)(data + 4);
13023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[2] = *(int *)(data + 8);
13123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out[3] = *(int *)(data + 12);
13223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			out += 4;
13323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			data += stride;
13423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		}
13523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
13623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
137f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid rcommon_emit_vector(struct gl_context * ctx, struct radeon_aos *aos,
138d534648d904da71e604babcf408c00eae7922d16Maciej Cencora			 const GLvoid * data, int size, int stride, int count)
13923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
14023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
14123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	uint32_t *out;
14223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
14323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (stride == 0) {
14423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * 4, 32);
14523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		count = 1;
14623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		aos->stride = 0;
14723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	} else {
14823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
14923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		aos->stride = size;
15023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
15123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
15223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	aos->components = size;
15323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	aos->count = count;
15423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
155bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	radeon_bo_map(aos->bo, 1);
15623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	out = (uint32_t*)((char*)aos->bo->ptr + aos->offset);
15723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	switch (size) {
15823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	case 1: radeonEmitVec4(out, data, stride, count); break;
15923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	case 2: radeonEmitVec8(out, data, stride, count); break;
16023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	case 3: radeonEmitVec12(out, data, stride, count); break;
16123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	case 4: radeonEmitVec16(out, data, stride, count); break;
16223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	default:
16323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		assert(0);
16423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		break;
16523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
166bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	radeon_bo_unmap(aos->bo);
16723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
16823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
16994556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deuchervoid rcommon_emit_vecfog(struct gl_context *ctx, struct radeon_aos *aos,
17094556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher			 GLvoid *data, int stride, int count)
17194556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher{
17294556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	int i;
17394556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	float *out;
17494556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	int size = 1;
17594556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
17694556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher
17794556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	if (RADEON_DEBUG & RADEON_VERTS)
17894556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		fprintf(stderr, "%s count %d stride %d\n",
17994556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher			__FUNCTION__, count, stride);
18094556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher
18194556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	if (stride == 0) {
18294556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		radeonAllocDmaRegion( rmesa, &aos->bo, &aos->offset, size * 4, 32 );
18394556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		count = 1;
18494556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		aos->stride = 0;
18594556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	} else {
18694556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		radeonAllocDmaRegion(rmesa, &aos->bo, &aos->offset, size * count * 4, 32);
18794556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		aos->stride = size;
18894556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	}
18994556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher
19094556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	aos->components = size;
19194556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	aos->count = count;
19294556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher
19394556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	/* Emit the data */
19494556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	radeon_bo_map(aos->bo, 1);
19594556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	out = (float*)((char*)aos->bo->ptr + aos->offset);
19694556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	for (i = 0; i < count; i++) {
19794556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		out[0] = radeonComputeFogBlendFactor( ctx, *(GLfloat *)data );
19894556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		out++;
19994556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher		data += stride;
20094556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	}
20194556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher	radeon_bo_unmap(aos->bo);
20294556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher}
20394556f359450acebe87d6c9b4f4fd8ccf78589d8Alex Deucher
204bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminenvoid radeon_init_dma(radeonContextPtr rmesa)
20523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
20666e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	make_empty_list(&rmesa->dma.free);
20766e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	make_empty_list(&rmesa->dma.wait);
20866e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	make_empty_list(&rmesa->dma.reserved);
20966e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	rmesa->dma.minimum_size = MAX_DMA_BUF_SZ;
210bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen}
21123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
212bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminenvoid radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
213bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen{
214c3374bf97ecd82b915fb29c7c04951e2b75d4dbcPauli Nieminen	struct radeon_dma_bo *dma_bo = NULL;
21566e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	/* we set minimum sizes to at least requested size
21666e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	   aligned to next 16 bytes. */
21766e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	if (size > rmesa->dma.minimum_size)
21866e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		rmesa->dma.minimum_size = (size + 15) & (~15);
21923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
220dab8f6b1d9781e91ce5102f1bb98f0e1b1b9a3cfMarek Olšák	radeon_print(RADEON_DMA, RADEON_NORMAL, "%s size %d minimum_size %Zi\n",
2214e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen			__FUNCTION__, size, rmesa->dma.minimum_size);
22223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
22366e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	if (is_empty_list(&rmesa->dma.free)
22466e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	      || last_elem(&rmesa->dma.free)->bo->size < size) {
225c3374bf97ecd82b915fb29c7c04951e2b75d4dbcPauli Nieminen		dma_bo = CALLOC_STRUCT(radeon_dma_bo);
226bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		assert(dma_bo);
22723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
2283149b87ac43a5f10983c6682dff7a00cf1d99c7crootagain_alloc:
229bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom,
23066e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen					    0, rmesa->dma.minimum_size, 4,
23166e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen					    RADEON_GEM_DOMAIN_GTT, 0);
23223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
233bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		if (!dma_bo->bo) {
234bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			rcommonFlushCmdBuf(rmesa, __FUNCTION__);
235bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			goto again_alloc;
236bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		}
237bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		insert_at_head(&rmesa->dma.reserved, dma_bo);
238bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	} else {
2390c0cea250d6615bbd500ac0b61b5d34bc61711cfPauli Nieminen		/* We push and pop buffers from end of list so we can keep
2400c0cea250d6615bbd500ac0b61b5d34bc61711cfPauli Nieminen		   counter on unused buffers for later freeing them from
2410c0cea250d6615bbd500ac0b61b5d34bc61711cfPauli Nieminen		   begin of list */
242c3374bf97ecd82b915fb29c7c04951e2b75d4dbcPauli Nieminen		dma_bo = last_elem(&rmesa->dma.free);
243bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
244bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		insert_at_head(&rmesa->dma.reserved, dma_bo);
24523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
24623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
24723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_used = 0;
24823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_vertexptr = 0;
2499a7776696b786180f1d384eb22b928707e74dfcaPauli Nieminen
250c27f21f92d2cf9d23a9edb15d144eceb9ff383bcDave Airlie	if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs,
251bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen					  first_elem(&rmesa->dma.reserved)->bo,
252c27f21f92d2cf9d23a9edb15d144eceb9ff383bcDave Airlie					  RADEON_GEM_DOMAIN_GTT, 0))
253c27f21f92d2cf9d23a9edb15d144eceb9ff383bcDave Airlie		fprintf(stderr,"failure to revalidate BOs - badness\n");
254d7cc0eb47930d6c8ebfd18fefbe48fe8eec696a0Jerome Glisse
255bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	if (is_empty_list(&rmesa->dma.reserved)) {
2569b1efcb87c794ded9306f01336d48a80aaad3261Jerome Glisse        /* Cmd buff have been flushed in radeon_revalidate_bos */
2579b1efcb87c794ded9306f01336d48a80aaad3261Jerome Glisse		goto again_alloc;
2589b1efcb87c794ded9306f01336d48a80aaad3261Jerome Glisse	}
2599a7776696b786180f1d384eb22b928707e74dfcaPauli Nieminen	radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1);
26023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
26123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
26223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie/* Allocates a region from rmesa->dma.current.  If there isn't enough
26323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie * space in current, grab a new buffer (and discard what was left of current)
26423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie */
26523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlievoid radeonAllocDmaRegion(radeonContextPtr rmesa,
26623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			  struct radeon_bo **pbo, int *poffset,
26723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie			  int bytes, int alignment)
26823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
2694e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_IOCTL)
27023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
27123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
27223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	if (rmesa->dma.flush)
27323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		rmesa->dma.flush(rmesa->glCtx);
27423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
27523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	assert(rmesa->dma.current_used == rmesa->dma.current_vertexptr);
27623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
27723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	alignment--;
27823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
27923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
280bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	if (is_empty_list(&rmesa->dma.reserved)
281bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		|| rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size)
28266e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		radeonRefillCurrentDmaRegion(rmesa, bytes);
28323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
28423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	*poffset = rmesa->dma.current_used;
285bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	*pbo = first_elem(&rmesa->dma.reserved)->bo;
28623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	radeon_bo_ref(*pbo);
28723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
28823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	/* Always align to at least 16 bytes */
28923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
29023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_vertexptr = rmesa->dma.current_used;
29123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
292bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	assert(rmesa->dma.current_used <= first_elem(&rmesa->dma.reserved)->bo->size);
293bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen}
294bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
295bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminenvoid radeonFreeDmaRegions(radeonContextPtr rmesa)
296bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen{
297796c96de808790826d9c9077d159390ebee62888Pauli Nieminen	struct radeon_dma_bo *dma_bo;
298bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	struct radeon_dma_bo *temp;
2994e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_DMA)
300bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		fprintf(stderr, "%s\n", __FUNCTION__);
301bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
302bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	foreach_s(dma_bo, temp, &rmesa->dma.free) {
303bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
304bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	        radeon_bo_unref(dma_bo->bo);
305bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		FREE(dma_bo);
306bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	}
307bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
308174aeabc0f00440e3d18813f0b461470448929fcAlex Deucher	foreach_s(dma_bo, temp, &rmesa->dma.wait) {
30966e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		remove_from_list(dma_bo);
31066e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	        radeon_bo_unref(dma_bo->bo);
31166e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		FREE(dma_bo);
31266e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen	}
31366e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen
314bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
315bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
316bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	        radeon_bo_unref(dma_bo->bo);
317bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		FREE(dma_bo);
318bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	}
31923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
32023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
3211279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlievoid radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes)
3221279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie{
3231279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie	if (is_empty_list(&rmesa->dma.reserved))
3241279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie		return;
3251279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie
3264e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_IOCTL)
3271279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie		fprintf(stderr, "%s %d\n", __FUNCTION__, return_bytes);
3281279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie	rmesa->dma.current_used -= return_bytes;
3291279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie	rmesa->dma.current_vertexptr = rmesa->dma.current_used;
3301279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie}
3311279cdcb1f3e37a91bb5252826386205dc3e579dDave Airlie
33266e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminenstatic int radeon_bo_is_idle(struct radeon_bo* bo)
33366e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen{
33466bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen	uint32_t domain;
33566bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen	int ret = radeon_bo_is_busy(bo, &domain);
33666bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen	if (ret == -EINVAL) {
33766bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen		WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n"
33866bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen			"This may cause small performance drop for you.\n");
33966bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen	}
34066bbafb6f9d44da3baddac6d948ba361182dde2aPauli Nieminen	return ret != -EBUSY;
34166e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen}
34266e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen
343bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminenvoid radeonReleaseDmaRegions(radeonContextPtr rmesa)
34423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
345bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	struct radeon_dma_bo *dma_bo;
346bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	struct radeon_dma_bo *temp;
347bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	const int expire_at = ++rmesa->dma.free.expire_counter + DMA_BO_FREE_TIME;
348bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	const int time = rmesa->dma.free.expire_counter;
349947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen
3504e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_DMA) {
351947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		size_t free = 0,
352947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		       wait = 0,
353947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		       reserved = 0;
354947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		foreach(dma_bo, &rmesa->dma.free)
355947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen			++free;
356947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen
357947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		foreach(dma_bo, &rmesa->dma.wait)
358947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen			++wait;
359947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen
360947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		foreach(dma_bo, &rmesa->dma.reserved)
361947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen			++reserved;
362947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen
3635d10890795d9bddc8cafc4afb19cacf164d6e667Pauli Nieminen		fprintf(stderr, "%s: free %zu, wait %zu, reserved %zu, minimum_size: %zu\n",
364947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen		      __FUNCTION__, free, wait, reserved, rmesa->dma.minimum_size);
365947df2e5a8e4e701db67219179fb9953df8ff6e6Pauli Nieminen	}
366bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
367bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	/* move waiting bos to free list.
368bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	   wait list provides gpu time to handle data before reuse */
369bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	foreach_s(dma_bo, temp, &rmesa->dma.wait) {
370bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		if (dma_bo->expire_counter == time) {
371bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			WARN_ONCE("Leaking dma buffer object!\n");
37213b5a624b1899c457279907d58046dfb3c95addcAlex Deucher			radeon_bo_unref(dma_bo->bo);
373bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			remove_from_list(dma_bo);
374bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			FREE(dma_bo);
375bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			continue;
376bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		}
37766e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		/* free objects that are too small to be used because of large request */
37866e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		if (dma_bo->bo->size < rmesa->dma.minimum_size) {
37966e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   radeon_bo_unref(dma_bo->bo);
38066e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   remove_from_list(dma_bo);
38166e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   FREE(dma_bo);
38266e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   continue;
38366e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		}
3849a7776696b786180f1d384eb22b928707e74dfcaPauli Nieminen		if (!radeon_bo_is_idle(dma_bo->bo)) {
38503855bc2accbeb508458f70bdbdcef292672b2b8Kristian Høgsberg			break;
3869a7776696b786180f1d384eb22b928707e74dfcaPauli Nieminen		}
387bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
388bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		dma_bo->expire_counter = expire_at;
389bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		insert_at_tail(&rmesa->dma.free, dma_bo);
390bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	}
391bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
392bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	/* move reserved to wait list */
393bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
394e9c2c4a76466fc1ccfbf4d5de048414f7126b940Pauli Nieminen		radeon_bo_unmap(dma_bo->bo);
39566e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		/* free objects that are too small to be used because of large request */
39666e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		if (dma_bo->bo->size < rmesa->dma.minimum_size) {
39766e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   radeon_bo_unref(dma_bo->bo);
39866e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   remove_from_list(dma_bo);
39966e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   FREE(dma_bo);
40066e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		   continue;
40166e019c6c91e6ae3fb9e26a12d7b7782a0095a8dPauli Nieminen		}
402bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
403bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		dma_bo->expire_counter = expire_at;
404bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		insert_at_tail(&rmesa->dma.wait, dma_bo);
405bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	}
406bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
407bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	/* free bos that have been unused for some time */
408bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	foreach_s(dma_bo, temp, &rmesa->dma.free) {
409bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		if (dma_bo->expire_counter != time)
410bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen			break;
411bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		remove_from_list(dma_bo);
412bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	        radeon_bo_unref(dma_bo->bo);
413bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		FREE(dma_bo);
41423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
415bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
41623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
41723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
41823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
41923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie/* Flush vertices in the current dma region.
42023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie */
421f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid rcommon_flush_last_swtcl_prim( struct gl_context *ctx  )
42223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
42323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
42423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	struct radeon_dma *dma = &rmesa->dma;
4259a7776696b786180f1d384eb22b928707e74dfcaPauli Nieminen
4264e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_IOCTL)
427bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		fprintf(stderr, "%s\n", __FUNCTION__);
42823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	dma->flush = NULL;
42923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
430bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	radeon_bo_unmap(rmesa->swtcl.bo);
431bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie
432bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen	if (!is_empty_list(&dma->reserved)) {
43323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	    GLuint current_offset = dma->current_used;
43423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
43523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	    assert (dma->current_used +
43623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		    rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
43723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		    dma->current_vertexptr);
43823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
43923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	    if (dma->current_used != dma->current_vertexptr) {
44023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		    dma->current_used = dma->current_vertexptr;
44123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
44223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie		    rmesa->vtbl.swtcl_flush(ctx, current_offset);
44323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	    }
44423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	    rmesa->swtcl.numverts = 0;
44523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
446bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	radeon_bo_unref(rmesa->swtcl.bo);
447bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	rmesa->swtcl.bo = NULL;
44823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
44923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie/* Alloc space in the current dma region.
45023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie */
45123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlievoid *
45223d3559bd4ece1fcab5513ebdaa38600d6654374Dave AirliercommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize )
45323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie{
45423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	GLuint bytes = vsize * nverts;
45523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	void *head;
4564e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_IOCTL)
457bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		fprintf(stderr, "%s\n", __FUNCTION__);
458bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie
4590926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen	if(is_empty_list(&rmesa->dma.reserved)
4600926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen	      ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) {
4610926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen		if (rmesa->dma.flush) {
4620926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen			rmesa->dma.flush(rmesa->glCtx);
4630926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen		}
4640926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen
46523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie                radeonRefillCurrentDmaRegion(rmesa, bytes);
4660926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen
4670926a5f4a110926711d0f8a4eb297dc772b09aa2Pauli Nieminen		return NULL;
46823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	}
46923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
47023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie        if (!rmesa->dma.flush) {
471f881035fd84add859b3e3dc4721eddd027005f49Dave Airlie		/* if cmdbuf flushed DMA restart */
47223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie                rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
47323d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie                rmesa->dma.flush = rcommon_flush_last_swtcl_prim;
47423d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie        }
47523d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
47623d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	ASSERT( vsize == rmesa->swtcl.vertex_size * 4 );
47723d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie        ASSERT( rmesa->dma.flush == rcommon_flush_last_swtcl_prim );
47823d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie        ASSERT( rmesa->dma.current_used +
47923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie                rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
48023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie                rmesa->dma.current_vertexptr );
48123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie
4822176b3ed9ab832122e56aed3242dfda102a5fec6Dave Airlie	if (!rmesa->swtcl.bo) {
4832176b3ed9ab832122e56aed3242dfda102a5fec6Dave Airlie		rmesa->swtcl.bo = first_elem(&rmesa->dma.reserved)->bo;
4842176b3ed9ab832122e56aed3242dfda102a5fec6Dave Airlie		radeon_bo_ref(rmesa->swtcl.bo);
4852176b3ed9ab832122e56aed3242dfda102a5fec6Dave Airlie		radeon_bo_map(rmesa->swtcl.bo, 1);
4862176b3ed9ab832122e56aed3242dfda102a5fec6Dave Airlie	}
487bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie
488bd13e6e5e2403ada2098e3a07c0af4b4ba989ab7Dave Airlie	head = (rmesa->swtcl.bo->ptr + rmesa->dma.current_vertexptr);
48923d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->dma.current_vertexptr += bytes;
49023d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	rmesa->swtcl.numverts += nverts;
49123d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie	return head;
49223d3559bd4ece1fcab5513ebdaa38600d6654374Dave Airlie}
493e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie
494f9995b30756140724f41daf963fa06167912be7fKristian Høgsbergvoid radeonReleaseArrays( struct gl_context *ctx, GLuint newinputs )
495e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie{
496e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie   radeonContextPtr radeon = RADEON_CONTEXT( ctx );
497e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie   int i;
4984e0d99a63588c67a955f797733da32d04e6f4ee6Pauli Nieminen	if (RADEON_DEBUG & RADEON_IOCTL)
499bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen		fprintf(stderr, "%s\n", __FUNCTION__);
500e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie
501a13e96359baaa0331561f86ef6487feba6540464Jerome Glisse   if (radeon->dma.flush) {
502a13e96359baaa0331561f86ef6487feba6540464Jerome Glisse       radeon->dma.flush(radeon->glCtx);
503a13e96359baaa0331561f86ef6487feba6540464Jerome Glisse   }
504e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie   for (i = 0; i < radeon->tcl.aos_count; i++) {
505e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie      if (radeon->tcl.aos[i].bo) {
506e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie         radeon_bo_unref(radeon->tcl.aos[i].bo);
507e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie         radeon->tcl.aos[i].bo = NULL;
508bbf2b5c4ffcb6755d34a5b698445aecf604e45fbPauli Nieminen
509e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie      }
510e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie   }
511e00ef43d796f0ae0247b1072bf0aa8cdd8e3034dDave Airlie}
512