Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
 
3
/*
4
 * Copyright (C) 2012 Rob Clark 
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice (including the next
14
 * paragraph) shall be included in all copies or substantial portions of the
15
 * Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 *
25
 * Authors:
26
 *    Rob Clark 
27
 */
28
 
29
#include "pipe/p_state.h"
30
#include "util/u_string.h"
31
#include "util/u_memory.h"
32
#include "util/u_prim.h"
33
#include "util/u_format.h"
34
 
35
#include "freedreno_draw.h"
36
#include "freedreno_context.h"
37
#include "freedreno_state.h"
38
#include "freedreno_resource.h"
39
#include "freedreno_util.h"
40
 
41
 
42
static enum pc_di_primtype
43
mode2primtype(unsigned mode)
44
{
45
	switch (mode) {
46
	case PIPE_PRIM_POINTS:         return DI_PT_POINTLIST;
47
	case PIPE_PRIM_LINES:          return DI_PT_LINELIST;
48
	case PIPE_PRIM_LINE_STRIP:     return DI_PT_LINESTRIP;
49
	case PIPE_PRIM_TRIANGLES:      return DI_PT_TRILIST;
50
	case PIPE_PRIM_TRIANGLE_STRIP: return DI_PT_TRISTRIP;
51
	case PIPE_PRIM_TRIANGLE_FAN:   return DI_PT_TRIFAN;
52
	case PIPE_PRIM_QUADS:          return DI_PT_QUADLIST;
53
	case PIPE_PRIM_QUAD_STRIP:     return DI_PT_QUADSTRIP;
54
	case PIPE_PRIM_POLYGON:        return DI_PT_POLYGON;
55
	}
56
	DBG("unsupported mode: (%s) %d", u_prim_name(mode), mode);
57
	assert(0);
58
	return DI_PT_NONE;
59
}
60
 
61
static enum pc_di_index_size
62
size2indextype(unsigned index_size)
63
{
64
	switch (index_size) {
65
	case 1: return INDEX_SIZE_8_BIT;
66
	case 2: return INDEX_SIZE_16_BIT;
67
	case 4: return INDEX_SIZE_32_BIT;
68
	}
69
	DBG("unsupported index size: %d", index_size);
70
	assert(0);
71
	return INDEX_SIZE_IGN;
72
}
73
 
74
/* this is same for a2xx/a3xx, so split into helper: */
75
void
76
fd_draw_emit(struct fd_context *ctx, const struct pipe_draw_info *info)
77
{
78
	struct fd_ringbuffer *ring = ctx->ring;
79
	struct pipe_index_buffer *idx = &ctx->indexbuf;
80
	struct fd_bo *idx_bo = NULL;
81
	enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
82
	enum pc_di_src_sel src_sel;
83
	uint32_t idx_size, idx_offset;
84
 
85
	if (info->indexed) {
86
		assert(!idx->user_buffer);
87
 
88
		idx_bo = fd_resource(idx->buffer)->bo;
89
		idx_type = size2indextype(idx->index_size);
90
		idx_size = idx->index_size * info->count;
91
		idx_offset = idx->offset;
92
		src_sel = DI_SRC_SEL_DMA;
93
	} else {
94
		idx_bo = NULL;
95
		idx_type = INDEX_SIZE_IGN;
96
		idx_size = 0;
97
		idx_offset = 0;
98
		src_sel = DI_SRC_SEL_AUTO_INDEX;
99
	}
100
 
101
	OUT_PKT3(ring, CP_DRAW_INDX, info->indexed ? 5 : 3);
102
	OUT_RING(ring, 0x00000000);        /* viz query info. */
103
	OUT_RING(ring, DRAW(mode2primtype(info->mode),
104
			src_sel, idx_type, IGNORE_VISIBILITY));
105
	OUT_RING(ring, info->count);       /* NumIndices */
106
	if (info->indexed) {
4401 Serge 107
		OUT_RELOC(ring, idx_bo, idx_offset, 0, 0);
4358 Serge 108
		OUT_RING (ring, idx_size);
109
	}
110
}
111
 
112
static void
113
fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
114
{
115
	struct fd_context *ctx = fd_context(pctx);
116
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
117
	struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
118
	unsigned i, buffers = 0;
119
 
120
	/* if we supported transform feedback, we'd have to disable this: */
121
	if (((scissor->maxx - scissor->minx) *
122
			(scissor->maxy - scissor->miny)) == 0) {
123
		return;
124
	}
125
 
126
	ctx->needs_flush = true;
127
 
128
	/*
129
	 * Figure out the buffers/features we need:
130
	 */
131
 
132
	if (fd_depth_enabled(ctx)) {
133
		buffers |= FD_BUFFER_DEPTH;
134
		fd_resource(pfb->zsbuf->texture)->dirty = true;
135
		ctx->gmem_reason |= FD_GMEM_DEPTH_ENABLED;
136
	}
137
 
138
	if (fd_stencil_enabled(ctx)) {
139
		buffers |= FD_BUFFER_STENCIL;
140
		fd_resource(pfb->zsbuf->texture)->dirty = true;
141
		ctx->gmem_reason |= FD_GMEM_STENCIL_ENABLED;
142
	}
143
 
144
	if (fd_logicop_enabled(ctx))
145
		ctx->gmem_reason |= FD_GMEM_LOGICOP_ENABLED;
146
 
147
	for (i = 0; i < pfb->nr_cbufs; i++) {
148
		struct pipe_resource *surf = pfb->cbufs[i]->texture;
149
 
150
		fd_resource(surf)->dirty = true;
151
		buffers |= FD_BUFFER_COLOR;
152
 
153
		if (surf->nr_samples > 1)
154
			ctx->gmem_reason |= FD_GMEM_MSAA_ENABLED;
155
 
156
		if (fd_blend_enabled(ctx, i))
157
			ctx->gmem_reason |= FD_GMEM_BLEND_ENABLED;
158
	}
159
 
160
	ctx->num_draws++;
161
 
162
	/* any buffers that haven't been cleared, we need to restore: */
163
	ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared);
164
	/* and any buffers used, need to be resolved: */
165
	ctx->resolve |= buffers;
166
 
167
	ctx->draw(ctx, info);
168
}
169
 
170
/* TODO figure out how to make better use of existing state mechanism
171
 * for clear (and possibly gmem->mem / mem->gmem) so we can (a) keep
172
 * track of what state really actually changes, and (b) reduce the code
173
 * in the a2xx/a3xx parts.
174
 */
175
 
176
static void
177
fd_clear(struct pipe_context *pctx, unsigned buffers,
178
		const union pipe_color_union *color, double depth, unsigned stencil)
179
{
180
	struct fd_context *ctx = fd_context(pctx);
181
	struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
182
 
183
	ctx->cleared |= buffers;
184
	ctx->resolve |= buffers;
185
	ctx->needs_flush = true;
186
 
187
	if (buffers & PIPE_CLEAR_COLOR)
188
		fd_resource(pfb->cbufs[0]->texture)->dirty = true;
189
 
190
	if (buffers & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) {
191
		fd_resource(pfb->zsbuf->texture)->dirty = true;
192
		ctx->gmem_reason |= FD_GMEM_CLEARS_DEPTH_STENCIL;
193
	}
194
 
195
	DBG("%x depth=%f, stencil=%u (%s/%s)", buffers, depth, stencil,
4401 Serge 196
		util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
197
		util_format_short_name(pipe_surface_format(pfb->zsbuf)));
4358 Serge 198
 
199
	ctx->clear(ctx, buffers, color, depth, stencil);
200
 
201
	ctx->dirty |= FD_DIRTY_ZSA |
202
			FD_DIRTY_RASTERIZER |
203
			FD_DIRTY_SAMPLE_MASK |
204
			FD_DIRTY_PROG |
205
			FD_DIRTY_CONSTBUF |
206
			FD_DIRTY_BLEND;
207
 
208
	if (fd_mesa_debug & FD_DBG_DCLEAR)
209
		ctx->dirty = 0xffffffff;
210
}
211
 
212
static void
213
fd_clear_render_target(struct pipe_context *pctx, struct pipe_surface *ps,
214
		const union pipe_color_union *color,
215
		unsigned x, unsigned y, unsigned w, unsigned h)
216
{
217
	DBG("TODO: x=%u, y=%u, w=%u, h=%u", x, y, w, h);
218
}
219
 
220
static void
221
fd_clear_depth_stencil(struct pipe_context *pctx, struct pipe_surface *ps,
222
		unsigned buffers, double depth, unsigned stencil,
223
		unsigned x, unsigned y, unsigned w, unsigned h)
224
{
225
	DBG("TODO: buffers=%u, depth=%f, stencil=%u, x=%u, y=%u, w=%u, h=%u",
226
			buffers, depth, stencil, x, y, w, h);
227
}
228
 
229
void
230
fd_draw_init(struct pipe_context *pctx)
231
{
232
	pctx->draw_vbo = fd_draw_vbo;
233
	pctx->clear = fd_clear;
234
	pctx->clear_render_target = fd_clear_render_target;
235
	pctx->clear_depth_stencil = fd_clear_depth_stencil;
236
}