1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright © 2011 Intel Corporation 3428d7b3dSmrg * 4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"), 6428d7b3dSmrg * to deal in the Software without restriction, including without limitation 7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions: 10428d7b3dSmrg * 11428d7b3dSmrg * The above copyright notice and this permission notice (including the next 12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the 13428d7b3dSmrg * Software. 14428d7b3dSmrg * 15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21428d7b3dSmrg * SOFTWARE. 22428d7b3dSmrg * 23428d7b3dSmrg * Authors: 24428d7b3dSmrg * Chris Wilson <chris@chris-wilson.co.uk> 25428d7b3dSmrg * 26428d7b3dSmrg */ 27428d7b3dSmrg 28428d7b3dSmrg#ifdef HAVE_CONFIG_H 29428d7b3dSmrg#include "config.h" 30428d7b3dSmrg#endif 31428d7b3dSmrg 32428d7b3dSmrg#include "sna.h" 33428d7b3dSmrg#include "sna_render.h" 34428d7b3dSmrg#include "brw/brw.h" 35428d7b3dSmrg 36428d7b3dSmrgint sna_static_stream_init(struct sna_static_stream *stream) 37428d7b3dSmrg{ 38428d7b3dSmrg stream->used = 0; 39428d7b3dSmrg stream->size = 64*1024; 40428d7b3dSmrg 41428d7b3dSmrg stream->data = malloc(stream->size); 42428d7b3dSmrg return stream->data != NULL; 43428d7b3dSmrg} 44428d7b3dSmrg 45428d7b3dSmrgstatic uint32_t sna_static_stream_alloc(struct sna_static_stream *stream, 46428d7b3dSmrg uint32_t len, uint32_t align) 47428d7b3dSmrg{ 48428d7b3dSmrg uint32_t offset = ALIGN(stream->used, align); 49428d7b3dSmrg uint32_t size = offset + len; 50428d7b3dSmrg 51428d7b3dSmrg if (size > stream->size) { 52428d7b3dSmrg do 53428d7b3dSmrg stream->size *= 2; 54428d7b3dSmrg while (stream->size < size); 55428d7b3dSmrg 56428d7b3dSmrg stream->data = realloc(stream->data, stream->size); 57428d7b3dSmrg } 58428d7b3dSmrg 59428d7b3dSmrg stream->used = size; 60428d7b3dSmrg return offset; 61428d7b3dSmrg} 62428d7b3dSmrg 63428d7b3dSmrguint32_t sna_static_stream_add(struct sna_static_stream *stream, 64428d7b3dSmrg const void *data, uint32_t len, uint32_t align) 65428d7b3dSmrg{ 66428d7b3dSmrg uint32_t offset = sna_static_stream_alloc(stream, len, align); 67428d7b3dSmrg memcpy(stream->data + offset, data, len); 68428d7b3dSmrg return offset; 69428d7b3dSmrg} 70428d7b3dSmrg 71428d7b3dSmrgvoid *sna_static_stream_map(struct sna_static_stream *stream, 72428d7b3dSmrg uint32_t len, uint32_t align) 73428d7b3dSmrg{ 74428d7b3dSmrg uint32_t offset = sna_static_stream_alloc(stream, len, align); 75428d7b3dSmrg return memset(stream->data + offset, 0, len); 76428d7b3dSmrg} 77428d7b3dSmrg 78428d7b3dSmrguint32_t sna_static_stream_offsetof(struct sna_static_stream *stream, void *ptr) 79428d7b3dSmrg{ 80428d7b3dSmrg return (uint8_t *)ptr - stream->data; 81428d7b3dSmrg} 82428d7b3dSmrg 83428d7b3dSmrgstruct kgem_bo *sna_static_stream_fini(struct sna *sna, 84428d7b3dSmrg struct sna_static_stream *stream) 85428d7b3dSmrg{ 86428d7b3dSmrg struct kgem_bo *bo; 87428d7b3dSmrg 88428d7b3dSmrg DBG(("uploaded %d bytes of static state\n", stream->used)); 89428d7b3dSmrg 90428d7b3dSmrg bo = kgem_create_linear(&sna->kgem, stream->used, 0); 91428d7b3dSmrg if (bo && !kgem_bo_write(&sna->kgem, bo, stream->data, stream->used)) { 92428d7b3dSmrg kgem_bo_destroy(&sna->kgem, bo); 93428d7b3dSmrg return NULL; 94428d7b3dSmrg } 95428d7b3dSmrg 96428d7b3dSmrg free(stream->data); 97428d7b3dSmrg 98428d7b3dSmrg return bo; 99428d7b3dSmrg} 100428d7b3dSmrg 101428d7b3dSmrgunsigned 102428d7b3dSmrgsna_static_stream_compile_sf(struct sna *sna, 103428d7b3dSmrg struct sna_static_stream *stream, 104428d7b3dSmrg bool (*compile)(struct brw_compile *)) 105428d7b3dSmrg{ 106428d7b3dSmrg struct brw_compile p; 107428d7b3dSmrg 108428d7b3dSmrg brw_compile_init(&p, sna->kgem.gen, 109428d7b3dSmrg sna_static_stream_map(stream, 110428d7b3dSmrg 64*sizeof(uint32_t), 64)); 111428d7b3dSmrg 112428d7b3dSmrg if (!compile(&p)) { 113428d7b3dSmrg stream->used -= 64*sizeof(uint32_t); 114428d7b3dSmrg return 0; 115428d7b3dSmrg } 116428d7b3dSmrg 117428d7b3dSmrg assert(p.nr_insn*sizeof(struct brw_instruction) <= 64*sizeof(uint32_t)); 118428d7b3dSmrg 119428d7b3dSmrg stream->used -= 64*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction); 120428d7b3dSmrg return sna_static_stream_offsetof(stream, p.store); 121428d7b3dSmrg} 122428d7b3dSmrg 123428d7b3dSmrgunsigned 124428d7b3dSmrgsna_static_stream_compile_wm(struct sna *sna, 125428d7b3dSmrg struct sna_static_stream *stream, 126428d7b3dSmrg bool (*compile)(struct brw_compile *, int), 127428d7b3dSmrg int dispatch_width) 128428d7b3dSmrg{ 129428d7b3dSmrg struct brw_compile p; 130428d7b3dSmrg 131428d7b3dSmrg brw_compile_init(&p, sna->kgem.gen, 132428d7b3dSmrg sna_static_stream_map(stream, 133428d7b3dSmrg 256*sizeof(uint32_t), 64)); 134428d7b3dSmrg 135428d7b3dSmrg if (!compile(&p, dispatch_width)) { 136428d7b3dSmrg stream->used -= 256*sizeof(uint32_t); 137428d7b3dSmrg return 0; 138428d7b3dSmrg } 139428d7b3dSmrg 140428d7b3dSmrg assert(p.nr_insn*sizeof(struct brw_instruction) <= 256*sizeof(uint32_t)); 141428d7b3dSmrg 142428d7b3dSmrg stream->used -= 256*sizeof(uint32_t) - p.nr_insn*sizeof(struct brw_instruction); 143428d7b3dSmrg return sna_static_stream_offsetof(stream, p.store); 144428d7b3dSmrg} 145