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) 2013 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_helpers.h"
33
#include "util/u_format.h"
34
 
35
#include "freedreno_resource.h"
36
 
37
#include "fd3_emit.h"
38
#include "fd3_blend.h"
39
#include "fd3_context.h"
40
#include "fd3_program.h"
41
#include "fd3_rasterizer.h"
42
#include "fd3_texture.h"
43
#include "fd3_util.h"
44
#include "fd3_zsa.h"
45
 
46
/* regid:          base const register
47
 * prsc or dwords: buffer containing constant values
48
 * sizedwords:     size of const value buffer
49
 */
50
void
51
fd3_emit_constant(struct fd_ringbuffer *ring,
52
		enum adreno_state_block sb,
53
		uint32_t regid, uint32_t offset, uint32_t sizedwords,
54
		const uint32_t *dwords, struct pipe_resource *prsc)
55
{
56
	uint32_t i, sz;
57
	enum adreno_state_src src;
58
 
59
	if (prsc) {
60
		sz = 0;
61
		src = SS_INDIRECT;
62
	} else {
63
		sz = sizedwords;
64
		src = SS_DIRECT;
65
	}
66
 
67
	/* we have this sometimes, not others.. perhaps we could be clever
68
	 * and figure out actually when we need to invalidate cache:
69
	 */
70
	OUT_PKT0(ring, REG_A3XX_UCHE_CACHE_INVALIDATE0_REG, 2);
71
	OUT_RING(ring, A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR(0));
72
	OUT_RING(ring, A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR(0) |
73
			A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(INVALIDATE) |
74
			A3XX_UCHE_CACHE_INVALIDATE1_REG_ENTIRE_CACHE);
75
 
76
	OUT_PKT3(ring, CP_LOAD_STATE, 2 + sz);
77
	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(regid/2) |
78
			CP_LOAD_STATE_0_STATE_SRC(src) |
79
			CP_LOAD_STATE_0_STATE_BLOCK(sb) |
80
			CP_LOAD_STATE_0_NUM_UNIT(sizedwords/2));
81
	if (prsc) {
82
		struct fd_bo *bo = fd_resource(prsc)->bo;
83
		OUT_RELOC(ring, bo, offset,
4401 Serge 84
				CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS), 0);
4358 Serge 85
	} else {
86
		OUT_RING(ring, CP_LOAD_STATE_1_EXT_SRC_ADDR(0) |
87
				CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS));
88
		dwords = (uint32_t *)&((uint8_t *)dwords)[offset];
89
	}
90
	for (i = 0; i < sz; i++) {
91
		OUT_RING(ring, dwords[i]);
92
	}
93
}
94
 
95
static void
96
emit_constants(struct fd_ringbuffer *ring,
97
		enum adreno_state_block sb,
98
		struct fd_constbuf_stateobj *constbuf,
99
		struct fd3_shader_stateobj *shader)
100
{
101
	uint32_t enabled_mask = constbuf->enabled_mask;
102
	uint32_t base = 0;
103
	unsigned i;
104
 
105
	// XXX TODO only emit dirty consts.. but we need to keep track if
106
	// they are clobbered by a clear, gmem2mem, or mem2gmem..
107
	constbuf->dirty_mask = enabled_mask;
108
 
109
	/* emit user constants: */
110
	while (enabled_mask) {
111
		unsigned index = ffs(enabled_mask) - 1;
112
		struct pipe_constant_buffer *cb = &constbuf->cb[index];
113
		unsigned size = align(cb->buffer_size, 4) / 4; /* size in dwords */
114
 
115
		// I expect that size should be a multiple of vec4's:
116
		assert(size == align(size, 4));
117
 
118
		/* gallium could have const-buffer still bound, even though the
119
		 * shader is not using it.  Writing consts above constlen (or
120
		 * rather, HLSQ_{VS,FS}_CONTROL_REG.CONSTLENGTH) will cause a
121
		 * hang.
122
		 */
123
		if ((base / 4) >= shader->constlen)
124
			break;
125
 
126
		if (constbuf->dirty_mask & (1 << index)) {
127
			fd3_emit_constant(ring, sb, base,
128
					cb->buffer_offset, size,
129
					cb->user_buffer, cb->buffer);
130
			constbuf->dirty_mask &= ~(1 << index);
131
		}
132
 
133
		base += size;
134
		enabled_mask &= ~(1 << index);
135
	}
136
 
137
	/* emit shader immediates: */
138
	if (shader) {
139
		for (i = 0; i < shader->immediates_count; i++) {
140
			fd3_emit_constant(ring, sb,
141
					4 * (shader->first_immediate + i),
142
					0, 4, shader->immediates[i].val, NULL);
143
		}
144
	}
145
}
146
 
147
#define VERT_TEX_OFF    0
148
#define FRAG_TEX_OFF    16
149
#define BASETABLE_SZ    14
150
 
151
static void
152
emit_textures(struct fd_ringbuffer *ring,
153
		enum adreno_state_block sb,
154
		struct fd_texture_stateobj *tex)
155
{
156
	static const unsigned tex_off[] = {
157
			[SB_VERT_TEX] = VERT_TEX_OFF,
158
			[SB_FRAG_TEX] = FRAG_TEX_OFF,
159
	};
160
	static const enum adreno_state_block mipaddr[] = {
161
			[SB_VERT_TEX] = SB_VERT_MIPADDR,
162
			[SB_FRAG_TEX] = SB_FRAG_MIPADDR,
163
	};
164
	unsigned i, j;
165
 
166
	assert(tex->num_samplers == tex->num_textures);  // TODO check..
167
 
168
	if (!tex->num_samplers)
169
		return;
170
 
171
	/* output sampler state: */
172
	OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
173
	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(tex_off[sb]) |
174
			CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
175
			CP_LOAD_STATE_0_STATE_BLOCK(sb) |
176
			CP_LOAD_STATE_0_NUM_UNIT(tex->num_samplers));
177
	OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_SHADER) |
178
			CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
179
	for (i = 0; i < tex->num_samplers; i++) {
180
		struct fd3_sampler_stateobj *sampler =
181
				fd3_sampler_stateobj(tex->samplers[i]);
182
		OUT_RING(ring, sampler->texsamp0);
183
		OUT_RING(ring, sampler->texsamp1);
184
	}
185
 
186
	/* emit texture state: */
187
	OUT_PKT3(ring, CP_LOAD_STATE, 2 + (4 * tex->num_textures));
188
	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(tex_off[sb]) |
189
			CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
190
			CP_LOAD_STATE_0_STATE_BLOCK(sb) |
191
			CP_LOAD_STATE_0_NUM_UNIT(tex->num_textures));
192
	OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
193
			CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
194
	for (i = 0; i < tex->num_textures; i++) {
195
		struct fd3_pipe_sampler_view *view =
196
				fd3_pipe_sampler_view(tex->textures[i]);
197
		OUT_RING(ring, view->texconst0);
198
		OUT_RING(ring, view->texconst1);
199
		OUT_RING(ring, view->texconst2 |
200
				A3XX_TEX_CONST_2_INDX(BASETABLE_SZ * i));
201
		OUT_RING(ring, view->texconst3);
202
	}
203
 
204
	/* emit mipaddrs: */
205
	OUT_PKT3(ring, CP_LOAD_STATE, 2 + (BASETABLE_SZ * tex->num_textures));
206
	OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(BASETABLE_SZ * tex_off[sb]) |
207
			CP_LOAD_STATE_0_STATE_SRC(SS_DIRECT) |
208
			CP_LOAD_STATE_0_STATE_BLOCK(mipaddr[sb]) |
209
			CP_LOAD_STATE_0_NUM_UNIT(BASETABLE_SZ * tex->num_textures));
210
	OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
211
			CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
212
	for (i = 0; i < tex->num_textures; i++) {
213
		struct fd3_pipe_sampler_view *view =
214
				fd3_pipe_sampler_view(tex->textures[i]);
4401 Serge 215
		OUT_RELOC(ring, view->tex_resource->bo, 0, 0, 0);
4358 Serge 216
		/* I think each entry is a ptr to mipmap level.. for now, just
217
		 * pad w/ null's until I get around to actually implementing
218
		 * mipmap support..
219
		 */
220
		for (j = 1; j < BASETABLE_SZ; j++) {
221
			OUT_RING(ring, 0x00000000);
222
		}
223
	}
224
}
225
 
226
static void
227
emit_cache_flush(struct fd_ringbuffer *ring)
228
{
229
	OUT_PKT3(ring, CP_EVENT_WRITE, 1);
230
	OUT_RING(ring, CACHE_FLUSH);
231
 
232
	OUT_PKT3(ring, CP_DRAW_INDX, 3);
233
	OUT_RING(ring, 0x00000000);
234
	OUT_RING(ring, DRAW(DI_PT_POINTLIST, DI_SRC_SEL_AUTO_INDEX,
235
			INDEX_SIZE_IGN, IGNORE_VISIBILITY));
236
	OUT_RING(ring, 0);					/* NumIndices */
237
 
238
	OUT_PKT3(ring, CP_NOP, 4);
239
	OUT_RING(ring, 0x00000000);
240
	OUT_RING(ring, 0x00000000);
241
	OUT_RING(ring, 0x00000000);
242
	OUT_RING(ring, 0x00000000);
243
 
244
	OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
245
	OUT_RING(ring, 0x00000000);
246
}
247
 
248
/* emit texture state for mem->gmem restore operation.. eventually it would
249
 * be good to get rid of this and use normal CSO/etc state for more of these
250
 * special cases, but for now the compiler is not sufficient..
251
 */
252
void
253
fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf)
254
{
255
	struct fd_resource *rsc = fd_resource(psurf->texture);
256