103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 2011 Intel Corporation
303b705cfSriastradh *
403b705cfSriastradh * Permission is hereby granted, free of charge, to any person obtaining a
503b705cfSriastradh * copy of this software and associated documentation files (the "Software"),
603b705cfSriastradh * to deal in the Software without restriction, including without limitation
703b705cfSriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
803b705cfSriastradh * and/or sell copies of the Software, and to permit persons to whom the
903b705cfSriastradh * Software is furnished to do so, subject to the following conditions:
1003b705cfSriastradh *
1103b705cfSriastradh * The above copyright notice and this permission notice (including the next
1203b705cfSriastradh * paragraph) shall be included in all copies or substantial portions of the
1303b705cfSriastradh * Software.
1403b705cfSriastradh *
1503b705cfSriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1603b705cfSriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1703b705cfSriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1803b705cfSriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1903b705cfSriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2003b705cfSriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2103b705cfSriastradh * SOFTWARE.
2203b705cfSriastradh *
2303b705cfSriastradh * Authors:
2403b705cfSriastradh *    Chris Wilson <chris@chris-wilson.co.uk>
2503b705cfSriastradh *
2603b705cfSriastradh */
2703b705cfSriastradh
2842542f5fSchristos#ifdef HAVE_CONFIG_H
2942542f5fSchristos#include "config.h"
3042542f5fSchristos#endif
3142542f5fSchristos
3203b705cfSriastradh#include "sna.h"
3303b705cfSriastradh#include "sna_render.h"
3403b705cfSriastradh#include "brw/brw.h"
3503b705cfSriastradh
3603b705cfSriastradhint sna_static_stream_init(struct sna_static_stream *stream)
3703b705cfSriastradh{
3803b705cfSriastradh	stream->used = 0;
3903b705cfSriastradh	stream->size = 64*1024;
4003b705cfSriastradh
4103b705cfSriastradh	stream->data = malloc(stream->size);
4203b705cfSriastradh	return stream->data != NULL;
4303b705cfSriastradh}
4403b705cfSriastradh
4503b705cfSriastradhstatic uint32_t sna_static_stream_alloc(struct sna_static_stream *stream,
4603b705cfSriastradh					uint32_t len, uint32_t align)
4703b705cfSriastradh{
4803b705cfSriastradh	uint32_t offset = ALIGN(stream->used, align);
4903b705cfSriastradh	uint32_t size = offset + len;
5003b705cfSriastradh
5103b705cfSriastradh	if (size > stream->size) {
5203b705cfSriastradh		do
5303b705cfSriastradh			stream->size *= 2;
5403b705cfSriastradh		while (stream->size < size);
5503b705cfSriastradh
5603b705cfSriastradh		stream->data = realloc(stream->data, stream->size);
5703b705cfSriastradh	}
5803b705cfSriastradh
5903b705cfSriastradh	stream->used = size;
6003b705cfSriastradh	return offset;
6103b705cfSriastradh}
6203b705cfSriastradh
6303b705cfSriastradhuint32_t sna_static_stream_add(struct sna_static_stream *stream,
6403b705cfSriastradh			       const void *data, uint32_t len, uint32_t align)
6503b705cfSriastradh{
6603b705cfSriastradh	uint32_t offset = sna_static_stream_alloc(stream, len, align);
6703b705cfSriastradh	memcpy(stream->data + offset, data, len);
6803b705cfSriastradh	return offset;
6903b705cfSriastradh}
7003b705cfSriastradh
7103b705cfSriastradhvoid *sna_static_stream_map(struct sna_static_stream *stream,
7203b705cfSriastradh			    uint32_t len, uint32_t align)
7303b705cfSriastradh{
7403b705cfSriastradh	uint32_t offset = sna_static_stream_alloc(stream, len, align);
7503b705cfSriastradh	return memset(stream->data + offset, 0, len);
7603b705cfSriastradh}
7703b705cfSriastradh
7803b705cfSriastradhuint32_t sna_static_stream_offsetof(struct sna_static_stream *stream, void *ptr)
7903b705cfSriastradh{
8003b705cfSriastradh	return (uint8_t *)ptr - stream->data;
8103b705cfSriastradh}
8203b705cfSriastradh
8303b705cfSriastradhstruct kgem_bo *sna_static_stream_fini(struct sna *sna,
8403b705cfSriastradh				       struct sna_static_stream *stream)
8503b705cfSriastradh{
8603b705cfSriastradh	struct kgem_bo *bo;
8703b705cfSriastradh
8803b705cfSriastradh	DBG(("uploaded %d bytes of static state\n", stream->used));
8903b705cfSriastradh
9003b705cfSriastradh	bo = kgem_create_linear(&sna->kgem, stream->used, 0);
9103b705cfSriastradh	if (bo && !kgem_bo_write(&sna->kgem, bo, stream->data, stream->used)) {
9203b705cfSriastradh		kgem_bo_destroy(&sna->kgem, bo);
9303b705cfSriastradh		return NULL;
9403b705cfSriastradh	}
9503b705cfSriastradh
9603b705cfSriastradh	free(stream->data);
9703b705cfSriastradh
9803b705cfSriastradh	return bo;
9903b705cfSriastradh}
10003b705cfSriastradh
10103b705cfSriastradhunsigned
10203b705cfSriastradhsna_static_stream_compile_sf(struct sna *sna,
10303b705cfSriastradh			     struct sna_static_stream *stream,
10403b705cfSriastradh			     bool (*compile)(struct brw_compile *))
10503b705cfSriastradh{
10603b705cfSriastradh	struct brw_compile p;
10703b705cfSriastradh
10803b705cfSriastradh	brw_compile_init(&p, sna->kgem.gen,
10903b705cfSriastradh			 sna_static_stream_map(stream,
11003b705cfSriastradh					       64*sizeof(uint32_t), 64));
11103b705cfSriastradh
11203b705cfSriastradh	if (!compile(&p)) {
11303b705cfSriastradh		stream->used -= 64*sizeof(uint32_t);
11403b705cfSriastradh		return 0;
11503b705cfSriastradh	}
11603b705cfSriastradh
11703b705cfSriastradh	assert(p.nr_insn*sizeof(struct brw_instruction) <= 64*sizeof(uint32_t));
11803b705cfSriastradh
11903b705cfSriastradh	stream->used -= 64*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction);
12003b705cfSriastradh	return sna_static_stream_offsetof(stream, p.store);
12103b705cfSriastradh}
12203b705cfSriastradh
12303b705cfSriastradhunsigned
12403b705cfSriastradhsna_static_stream_compile_wm(struct sna *sna,
12503b705cfSriastradh			     struct sna_static_stream *stream,
12603b705cfSriastradh			     bool (*compile)(struct brw_compile *, int),
12703b705cfSriastradh			     int dispatch_width)
12803b705cfSriastradh{
12903b705cfSriastradh	struct brw_compile p;
13003b705cfSriastradh
13103b705cfSriastradh	brw_compile_init(&p, sna->kgem.gen,
13203b705cfSriastradh			 sna_static_stream_map(stream,
13303b705cfSriastradh					       256*sizeof(uint32_t), 64));
13403b705cfSriastradh
13503b705cfSriastradh	if (!compile(&p, dispatch_width)) {
13603b705cfSriastradh		stream->used -= 256*sizeof(uint32_t);
13703b705cfSriastradh		return 0;
13803b705cfSriastradh	}
13903b705cfSriastradh
14003b705cfSriastradh	assert(p.nr_insn*sizeof(struct brw_instruction) <= 256*sizeof(uint32_t));
14103b705cfSriastradh
14203b705cfSriastradh	stream->used -= 256*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction);
14303b705cfSriastradh	return sna_static_stream_offsetof(stream, p.store);
14403b705cfSriastradh}
145