103b705cfSriastradh/* 203b705cfSriastradh * Copyright © 2007-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 * Eric Anholt <eric@anholt.net> 2503b705cfSriastradh * Chris Wilson <chris"chris-wilson.co.uk> 2603b705cfSriastradh * 2703b705cfSriastradh */ 2803b705cfSriastradh 2903b705cfSriastradh#ifdef HAVE_CONFIG_H 3003b705cfSriastradh#include "config.h" 3103b705cfSriastradh#endif 3203b705cfSriastradh 3303b705cfSriastradh#include <sys/mman.h> 3403b705cfSriastradh#include <assert.h> 3503b705cfSriastradh 3603b705cfSriastradh#include "sna.h" 3703b705cfSriastradh#include "sna_reg.h" 3803b705cfSriastradh#include "gen7_render.h" 3903b705cfSriastradh 4003b705cfSriastradh#include "kgem_debug.h" 4103b705cfSriastradh 4203b705cfSriastradhstatic struct state { 4303b705cfSriastradh struct vertex_buffer { 4403b705cfSriastradh int handle; 4503b705cfSriastradh void *base; 4603b705cfSriastradh const char *ptr; 4703b705cfSriastradh int pitch; 4803b705cfSriastradh 4903b705cfSriastradh struct kgem_bo *current; 5003b705cfSriastradh } vb[33]; 5103b705cfSriastradh struct vertex_elements { 5203b705cfSriastradh int buffer; 5303b705cfSriastradh int offset; 5403b705cfSriastradh bool valid; 5503b705cfSriastradh uint32_t type; 5603b705cfSriastradh uint8_t swizzle[4]; 5703b705cfSriastradh } ve[33]; 5803b705cfSriastradh int num_ve; 5903b705cfSriastradh 6003b705cfSriastradh struct dynamic_state { 6103b705cfSriastradh struct kgem_bo *current; 6203b705cfSriastradh void *base, *ptr; 6303b705cfSriastradh } dynamic_state; 6403b705cfSriastradh} state; 6503b705cfSriastradh 6603b705cfSriastradhstatic void gen7_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) 6703b705cfSriastradh{ 6803b705cfSriastradh uint32_t reloc = sizeof(uint32_t) * (&data[1] - kgem->batch); 6903b705cfSriastradh struct kgem_bo *bo = NULL; 7003b705cfSriastradh void *base, *ptr; 7103b705cfSriastradh int i; 7203b705cfSriastradh 7303b705cfSriastradh for (i = 0; i < kgem->nreloc; i++) 7403b705cfSriastradh if (kgem->reloc[i].offset == reloc) 7503b705cfSriastradh break; 7603b705cfSriastradh assert(i < kgem->nreloc); 7703b705cfSriastradh reloc = kgem->reloc[i].target_handle; 7803b705cfSriastradh 7903b705cfSriastradh if (reloc == 0) { 8003b705cfSriastradh base = kgem->batch; 8103b705cfSriastradh } else { 8203b705cfSriastradh list_for_each_entry(bo, &kgem->next_request->buffers, request) 8303b705cfSriastradh if (bo->handle == reloc) 8403b705cfSriastradh break; 8503b705cfSriastradh assert(&bo->request != &kgem->next_request->buffers); 8603b705cfSriastradh base = kgem_bo_map__debug(kgem, bo); 8703b705cfSriastradh } 8803b705cfSriastradh ptr = (char *)base + kgem->reloc[i].delta; 8903b705cfSriastradh 9003b705cfSriastradh i = data[0] >> 26; 9103b705cfSriastradh 9203b705cfSriastradh state.vb[i].current = bo; 9303b705cfSriastradh state.vb[i].base = base; 9403b705cfSriastradh state.vb[i].ptr = ptr; 9503b705cfSriastradh state.vb[i].pitch = data[0] & 0x7ff; 9603b705cfSriastradh} 9703b705cfSriastradh 9803b705cfSriastradhstatic void gen7_update_dynamic_buffer(struct kgem *kgem, const uint32_t offset) 9903b705cfSriastradh{ 10003b705cfSriastradh uint32_t reloc = sizeof(uint32_t) * offset; 10103b705cfSriastradh struct kgem_bo *bo = NULL; 10203b705cfSriastradh void *base, *ptr; 10303b705cfSriastradh int i; 10403b705cfSriastradh 10503b705cfSriastradh if ((kgem->batch[offset] & 1) == 0) 10603b705cfSriastradh return; 10703b705cfSriastradh 10803b705cfSriastradh for (i = 0; i < kgem->nreloc; i++) 10903b705cfSriastradh if (kgem->reloc[i].offset == reloc) 11003b705cfSriastradh break; 11103b705cfSriastradh if(i < kgem->nreloc) { 11203b705cfSriastradh reloc = kgem->reloc[i].target_handle; 11303b705cfSriastradh 11403b705cfSriastradh if (reloc == 0) { 11503b705cfSriastradh base = kgem->batch; 11603b705cfSriastradh } else { 11703b705cfSriastradh list_for_each_entry(bo, &kgem->next_request->buffers, request) 11803b705cfSriastradh if (bo->handle == reloc) 11903b705cfSriastradh break; 12003b705cfSriastradh assert(&bo->request != &kgem->next_request->buffers); 12103b705cfSriastradh base = kgem_bo_map__debug(kgem, bo); 12203b705cfSriastradh } 12303b705cfSriastradh ptr = (char *)base + (kgem->reloc[i].delta & ~1); 12403b705cfSriastradh } else { 12503b705cfSriastradh bo = NULL; 12603b705cfSriastradh base = NULL; 12703b705cfSriastradh ptr = NULL; 12803b705cfSriastradh } 12903b705cfSriastradh 13003b705cfSriastradh state.dynamic_state.current = bo; 13103b705cfSriastradh state.dynamic_state.base = base; 13203b705cfSriastradh state.dynamic_state.ptr = ptr; 13303b705cfSriastradh} 13403b705cfSriastradh 13503b705cfSriastradhstatic uint32_t 13603b705cfSriastradhget_ve_component(uint32_t data, int component) 13703b705cfSriastradh{ 13803b705cfSriastradh return (data >> (16 + (3 - component) * 4)) & 0x7; 13903b705cfSriastradh} 14003b705cfSriastradh 14103b705cfSriastradhstatic void gen7_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) 14203b705cfSriastradh{ 14303b705cfSriastradh state.ve[id].buffer = data[0] >> 26; 14403b705cfSriastradh state.ve[id].valid = !!(data[0] & (1 << 25)); 14503b705cfSriastradh state.ve[id].type = (data[0] >> 16) & 0x1ff; 14603b705cfSriastradh state.ve[id].offset = data[0] & 0x7ff; 14703b705cfSriastradh state.ve[id].swizzle[0] = get_ve_component(data[1], 0); 14803b705cfSriastradh state.ve[id].swizzle[1] = get_ve_component(data[1], 1); 14903b705cfSriastradh state.ve[id].swizzle[2] = get_ve_component(data[1], 2); 15003b705cfSriastradh state.ve[id].swizzle[3] = get_ve_component(data[1], 3); 15103b705cfSriastradh} 15203b705cfSriastradh 15303b705cfSriastradhstatic void gen7_update_sf_state(struct kgem *kgem, uint32_t *data) 15403b705cfSriastradh{ 15503b705cfSriastradh state.num_ve = 1 + ((data[1] >> 22) & 0x3f); 15603b705cfSriastradh} 15703b705cfSriastradh 15803b705cfSriastradhstatic void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) 15903b705cfSriastradh{ 16003b705cfSriastradh int c; 16103b705cfSriastradh 16203b705cfSriastradh ErrorF("("); 16303b705cfSriastradh for (c = 0; c < max; c++) { 16403b705cfSriastradh switch (ve->swizzle[c]) { 16503b705cfSriastradh case 0: ErrorF("#"); break; 16603b705cfSriastradh case 1: ErrorF("%d", v[c]); break; 16703b705cfSriastradh case 2: ErrorF("0.0"); break; 16803b705cfSriastradh case 3: ErrorF("1.0"); break; 16903b705cfSriastradh case 4: ErrorF("0x1"); break; 17003b705cfSriastradh case 5: break; 17103b705cfSriastradh default: ErrorF("?"); 17203b705cfSriastradh } 17303b705cfSriastradh if (c < 3) 17403b705cfSriastradh ErrorF(", "); 17503b705cfSriastradh } 17603b705cfSriastradh for (; c < 4; c++) { 17703b705cfSriastradh switch (ve->swizzle[c]) { 17803b705cfSriastradh case 0: ErrorF("#"); break; 17903b705cfSriastradh case 1: ErrorF("1.0"); break; 18003b705cfSriastradh case 2: ErrorF("0.0"); break; 18103b705cfSriastradh case 3: ErrorF("1.0"); break; 18203b705cfSriastradh case 4: ErrorF("0x1"); break; 18303b705cfSriastradh case 5: break; 18403b705cfSriastradh default: ErrorF("?"); 18503b705cfSriastradh } 18603b705cfSriastradh if (c < 3) 18703b705cfSriastradh ErrorF(", "); 18803b705cfSriastradh } 18903b705cfSriastradh ErrorF(")"); 19003b705cfSriastradh} 19103b705cfSriastradh 19203b705cfSriastradhstatic void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) 19303b705cfSriastradh{ 19403b705cfSriastradh int c, o; 19503b705cfSriastradh 19603b705cfSriastradh ErrorF("("); 19703b705cfSriastradh for (c = o = 0; c < 4 && o < max; c++) { 19803b705cfSriastradh switch (ve->swizzle[c]) { 19903b705cfSriastradh case 0: ErrorF("#"); break; 20003b705cfSriastradh case 1: ErrorF("%f", f[o++]); break; 20103b705cfSriastradh case 2: ErrorF("0.0"); break; 20203b705cfSriastradh case 3: ErrorF("1.0"); break; 20303b705cfSriastradh case 4: ErrorF("0x1"); break; 20403b705cfSriastradh case 5: break; 20503b705cfSriastradh default: ErrorF("?"); 20603b705cfSriastradh } 20703b705cfSriastradh if (c < 3) 20803b705cfSriastradh ErrorF(", "); 20903b705cfSriastradh } 21003b705cfSriastradh for (; c < 4; c++) { 21103b705cfSriastradh switch (ve->swizzle[c]) { 21203b705cfSriastradh case 0: ErrorF("#"); break; 21303b705cfSriastradh case 1: ErrorF("1.0"); break; 21403b705cfSriastradh case 2: ErrorF("0.0"); break; 21503b705cfSriastradh case 3: ErrorF("1.0"); break; 21603b705cfSriastradh case 4: ErrorF("0x1"); break; 21703b705cfSriastradh case 5: break; 21803b705cfSriastradh default: ErrorF("?"); 21903b705cfSriastradh } 22003b705cfSriastradh if (c < 3) 22103b705cfSriastradh ErrorF(", "); 22203b705cfSriastradh } 22303b705cfSriastradh ErrorF(")"); 22403b705cfSriastradh} 22503b705cfSriastradh 22603b705cfSriastradhstatic void ve_out(const struct vertex_elements *ve, const void *ptr) 22703b705cfSriastradh{ 22803b705cfSriastradh switch (ve->type) { 22903b705cfSriastradh case GEN7_SURFACEFORMAT_R32_FLOAT: 23003b705cfSriastradh vertices_float_out(ve, ptr, 1); 23103b705cfSriastradh break; 23203b705cfSriastradh case GEN7_SURFACEFORMAT_R32G32_FLOAT: 23303b705cfSriastradh vertices_float_out(ve, ptr, 2); 23403b705cfSriastradh break; 23503b705cfSriastradh case GEN7_SURFACEFORMAT_R32G32B32_FLOAT: 23603b705cfSriastradh vertices_float_out(ve, ptr, 3); 23703b705cfSriastradh break; 23803b705cfSriastradh case GEN7_SURFACEFORMAT_R32G32B32A32_FLOAT: 23903b705cfSriastradh vertices_float_out(ve, ptr, 4); 24003b705cfSriastradh break; 24103b705cfSriastradh case GEN7_SURFACEFORMAT_R16_SINT: 24203b705cfSriastradh vertices_sint16_out(ve, ptr, 1); 24303b705cfSriastradh break; 24403b705cfSriastradh case GEN7_SURFACEFORMAT_R16G16_SINT: 24503b705cfSriastradh vertices_sint16_out(ve, ptr, 2); 24603b705cfSriastradh break; 24703b705cfSriastradh case GEN7_SURFACEFORMAT_R16G16B16A16_SINT: 24803b705cfSriastradh vertices_sint16_out(ve, ptr, 4); 24903b705cfSriastradh break; 25003b705cfSriastradh case GEN7_SURFACEFORMAT_R16_SSCALED: 25103b705cfSriastradh vertices_sint16_out(ve, ptr, 1); 25203b705cfSriastradh break; 25303b705cfSriastradh case GEN7_SURFACEFORMAT_R16G16_SSCALED: 25403b705cfSriastradh vertices_sint16_out(ve, ptr, 2); 25503b705cfSriastradh break; 25603b705cfSriastradh case GEN7_SURFACEFORMAT_R16G16B16A16_SSCALED: 25703b705cfSriastradh vertices_sint16_out(ve, ptr, 4); 25803b705cfSriastradh break; 25903b705cfSriastradh } 26003b705cfSriastradh} 26103b705cfSriastradh 26203b705cfSriastradhstatic void indirect_vertex_out(struct kgem *kgem, uint32_t v) 26303b705cfSriastradh{ 26403b705cfSriastradh int i = 1; 26503b705cfSriastradh 26603b705cfSriastradh do { 26703b705cfSriastradh const struct vertex_elements *ve = &state.ve[i]; 26803b705cfSriastradh const struct vertex_buffer *vb = &state.vb[ve->buffer]; 26903b705cfSriastradh const void *ptr = vb->ptr + v * vb->pitch + ve->offset; 27003b705cfSriastradh 27103b705cfSriastradh if (!ve->valid) 27203b705cfSriastradh continue; 27303b705cfSriastradh 27403b705cfSriastradh ve_out(ve, ptr); 27503b705cfSriastradh 27603b705cfSriastradh while (++i <= state.num_ve && !state.ve[i].valid) 27703b705cfSriastradh ; 27803b705cfSriastradh 27903b705cfSriastradh if (i <= state.num_ve) 28003b705cfSriastradh ErrorF(", "); 28103b705cfSriastradh } while (i <= state.num_ve); 28203b705cfSriastradh} 28303b705cfSriastradh 28403b705cfSriastradhstatic void primitive_out(struct kgem *kgem, uint32_t *data) 28503b705cfSriastradh{ 28603b705cfSriastradh int n; 28703b705cfSriastradh 28803b705cfSriastradh assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ 28903b705cfSriastradh 29003b705cfSriastradh for (n = 0; n < data[2]; n++) { 29103b705cfSriastradh int v = data[3] + n; 29203b705cfSriastradh ErrorF(" [%d:%d] = ", n, v); 29303b705cfSriastradh indirect_vertex_out(kgem, v); 29403b705cfSriastradh ErrorF("\n"); 29503b705cfSriastradh } 29603b705cfSriastradh} 29703b705cfSriastradh 29803b705cfSriastradhstatic void finish_state(struct kgem *kgem) 29903b705cfSriastradh{ 30003b705cfSriastradh memset(&state, 0, sizeof(state)); 30103b705cfSriastradh} 30203b705cfSriastradh 30303b705cfSriastradhstatic void 30403b705cfSriastradhstate_base_out(uint32_t *data, uint32_t offset, unsigned int index, 30503b705cfSriastradh const char *name) 30603b705cfSriastradh{ 30703b705cfSriastradh if (data[index] & 1) 30803b705cfSriastradh kgem_debug_print(data, offset, index, 30903b705cfSriastradh "%s state base address 0x%08x\n", 31003b705cfSriastradh name, data[index] & ~1); 31103b705cfSriastradh else 31203b705cfSriastradh kgem_debug_print(data, offset, index, 31303b705cfSriastradh "%s state base not updated\n", 31403b705cfSriastradh name); 31503b705cfSriastradh} 31603b705cfSriastradh 31703b705cfSriastradhstatic void 31803b705cfSriastradhstate_max_out(uint32_t *data, uint32_t offset, unsigned int index, 31903b705cfSriastradh const char *name) 32003b705cfSriastradh{ 32103b705cfSriastradh if (data[index] == 1) 32203b705cfSriastradh kgem_debug_print(data, offset, index, 32303b705cfSriastradh "%s state upper bound disabled\n", name); 32403b705cfSriastradh else if (data[index] & 1) 32503b705cfSriastradh kgem_debug_print(data, offset, index, 32603b705cfSriastradh "%s state upper bound 0x%08x\n", 32703b705cfSriastradh name, data[index] & ~1); 32803b705cfSriastradh else 32903b705cfSriastradh kgem_debug_print(data, offset, index, 33003b705cfSriastradh "%s state upper bound not updated\n", 33103b705cfSriastradh name); 33203b705cfSriastradh} 33303b705cfSriastradh 33403b705cfSriastradhstatic const char * 33503b705cfSriastradhget_965_surfacetype(unsigned int surfacetype) 33603b705cfSriastradh{ 33703b705cfSriastradh switch (surfacetype) { 33803b705cfSriastradh case 0: return "1D"; 33903b705cfSriastradh case 1: return "2D"; 34003b705cfSriastradh case 2: return "3D"; 34103b705cfSriastradh case 3: return "CUBE"; 34203b705cfSriastradh case 4: return "BUFFER"; 34303b705cfSriastradh case 7: return "NULL"; 34403b705cfSriastradh default: return "unknown"; 34503b705cfSriastradh } 34603b705cfSriastradh} 34703b705cfSriastradh 34803b705cfSriastradhstatic const char * 34903b705cfSriastradhget_965_depthformat(unsigned int depthformat) 35003b705cfSriastradh{ 35103b705cfSriastradh switch (depthformat) { 35203b705cfSriastradh case 0: return "s8_z24float"; 35303b705cfSriastradh case 1: return "z32float"; 35403b705cfSriastradh case 2: return "z24s8"; 35503b705cfSriastradh case 5: return "z16"; 35603b705cfSriastradh default: return "unknown"; 35703b705cfSriastradh } 35803b705cfSriastradh} 35903b705cfSriastradh 36003b705cfSriastradhstatic const char * 36103b705cfSriastradhget_element_component(uint32_t data, int component) 36203b705cfSriastradh{ 36303b705cfSriastradh uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; 36403b705cfSriastradh 36503b705cfSriastradh switch (component_control) { 36603b705cfSriastradh case 0: 36703b705cfSriastradh return "nostore"; 36803b705cfSriastradh case 1: 36903b705cfSriastradh switch (component) { 37003b705cfSriastradh case 0: return "X"; 37103b705cfSriastradh case 1: return "Y"; 37203b705cfSriastradh case 2: return "Z"; 37303b705cfSriastradh case 3: return "W"; 37403b705cfSriastradh default: return "fail"; 37503b705cfSriastradh } 37603b705cfSriastradh case 2: 37703b705cfSriastradh return "0.0"; 37803b705cfSriastradh case 3: 37903b705cfSriastradh return "1.0"; 38003b705cfSriastradh case 4: 38103b705cfSriastradh return "0x1"; 38203b705cfSriastradh case 5: 38303b705cfSriastradh return "VID"; 38403b705cfSriastradh default: 38503b705cfSriastradh return "fail"; 38603b705cfSriastradh } 38703b705cfSriastradh} 38803b705cfSriastradh 38903b705cfSriastradhstatic const char * 39003b705cfSriastradhget_prim_type(uint32_t data) 39103b705cfSriastradh{ 39203b705cfSriastradh uint32_t primtype = data & 0x1f; 39303b705cfSriastradh 39403b705cfSriastradh switch (primtype) { 39503b705cfSriastradh case 0x01: return "point list"; 39603b705cfSriastradh case 0x02: return "line list"; 39703b705cfSriastradh case 0x03: return "line strip"; 39803b705cfSriastradh case 0x04: return "tri list"; 39903b705cfSriastradh case 0x05: return "tri strip"; 40003b705cfSriastradh case 0x06: return "tri fan"; 40103b705cfSriastradh case 0x07: return "quad list"; 40203b705cfSriastradh case 0x08: return "quad strip"; 40303b705cfSriastradh case 0x09: return "line list adj"; 40403b705cfSriastradh case 0x0a: return "line strip adj"; 40503b705cfSriastradh case 0x0b: return "tri list adj"; 40603b705cfSriastradh case 0x0c: return "tri strip adj"; 40703b705cfSriastradh case 0x0d: return "tri strip reverse"; 40803b705cfSriastradh case 0x0e: return "polygon"; 40903b705cfSriastradh case 0x0f: return "rect list"; 41003b705cfSriastradh case 0x10: return "line loop"; 41103b705cfSriastradh case 0x11: return "point list bf"; 41203b705cfSriastradh case 0x12: return "line strip cont"; 41303b705cfSriastradh case 0x13: return "line strip bf"; 41403b705cfSriastradh case 0x14: return "line strip cont bf"; 41503b705cfSriastradh case 0x15: return "tri fan no stipple"; 41603b705cfSriastradh default: return "fail"; 41703b705cfSriastradh } 41803b705cfSriastradh} 41903b705cfSriastradh 42003b705cfSriastradhstruct reloc { 42103b705cfSriastradh struct kgem_bo *bo; 42203b705cfSriastradh void *base; 42303b705cfSriastradh}; 42403b705cfSriastradh 42503b705cfSriastradhstatic void * 42603b705cfSriastradhget_reloc(struct kgem *kgem, 42703b705cfSriastradh void *base, const uint32_t *reloc, 42803b705cfSriastradh struct reloc *r) 42903b705cfSriastradh{ 43003b705cfSriastradh uint32_t delta = *reloc; 43103b705cfSriastradh 43203b705cfSriastradh memset(r, 0, sizeof(*r)); 43303b705cfSriastradh 43403b705cfSriastradh if (base == 0) { 43503b705cfSriastradh uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); 43603b705cfSriastradh struct kgem_bo *bo = NULL; 43703b705cfSriastradh int i; 43803b705cfSriastradh 43903b705cfSriastradh for (i = 0; i < kgem->nreloc; i++) 44003b705cfSriastradh if (kgem->reloc[i].offset == handle) 44103b705cfSriastradh break; 44203b705cfSriastradh assert(i < kgem->nreloc); 44303b705cfSriastradh handle = kgem->reloc[i].target_handle; 44403b705cfSriastradh delta = kgem->reloc[i].delta; 44503b705cfSriastradh 44603b705cfSriastradh if (handle == 0) { 44703b705cfSriastradh base = kgem->batch; 44803b705cfSriastradh } else { 44903b705cfSriastradh list_for_each_entry(bo, &kgem->next_request->buffers, request) 45003b705cfSriastradh if (bo->handle == handle) 45103b705cfSriastradh break; 45203b705cfSriastradh assert(&bo->request != &kgem->next_request->buffers); 45303b705cfSriastradh base = kgem_bo_map__debug(kgem, bo); 45403b705cfSriastradh r->bo = bo; 45503b705cfSriastradh r->base = base; 45603b705cfSriastradh } 45703b705cfSriastradh } 45803b705cfSriastradh 45903b705cfSriastradh return (char *)base + (delta & ~3); 46003b705cfSriastradh} 46103b705cfSriastradh 46203b705cfSriastradhstatic const char * 46303b705cfSriastradhgen7_filter_to_string(uint32_t filter) 46403b705cfSriastradh{ 46503b705cfSriastradh switch (filter) { 46603b705cfSriastradh default: 46703b705cfSriastradh case GEN7_MAPFILTER_NEAREST: return "nearest"; 46803b705cfSriastradh case GEN7_MAPFILTER_LINEAR: return "linear"; 46903b705cfSriastradh } 47003b705cfSriastradh} 47103b705cfSriastradh 47203b705cfSriastradhstatic const char * 47303b705cfSriastradhgen7_repeat_to_string(uint32_t repeat) 47403b705cfSriastradh{ 47503b705cfSriastradh switch (repeat) { 47603b705cfSriastradh default: 47703b705cfSriastradh case GEN7_TEXCOORDMODE_CLAMP_BORDER: return "border"; 47803b705cfSriastradh case GEN7_TEXCOORDMODE_WRAP: return "wrap"; 47903b705cfSriastradh case GEN7_TEXCOORDMODE_CLAMP: return "clamp"; 48003b705cfSriastradh case GEN7_TEXCOORDMODE_MIRROR: return "mirror"; 48103b705cfSriastradh } 48203b705cfSriastradh} 48303b705cfSriastradh 48403b705cfSriastradhstatic void 48503b705cfSriastradhgen7_decode_sampler_state(struct kgem *kgem, const uint32_t *reloc) 48603b705cfSriastradh{ 48703b705cfSriastradh const struct gen7_sampler_state *ss; 48803b705cfSriastradh struct reloc r; 48903b705cfSriastradh const char *min, *mag; 49003b705cfSriastradh const char *s_wrap, *t_wrap, *r_wrap; 49103b705cfSriastradh 49203b705cfSriastradh ss = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); 49303b705cfSriastradh 49403b705cfSriastradh min = gen7_filter_to_string(ss->ss0.min_filter); 49503b705cfSriastradh mag = gen7_filter_to_string(ss->ss0.mag_filter); 49603b705cfSriastradh 49703b705cfSriastradh s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode); 49803b705cfSriastradh t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode); 49903b705cfSriastradh r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode); 50003b705cfSriastradh 50103b705cfSriastradh ErrorF(" Sampler 0:\n"); 50203b705cfSriastradh ErrorF(" filter: min=%s, mag=%s\n", min, mag); 50303b705cfSriastradh ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); 50403b705cfSriastradh 50503b705cfSriastradh ss++; 50603b705cfSriastradh min = gen7_filter_to_string(ss->ss0.min_filter); 50703b705cfSriastradh mag = gen7_filter_to_string(ss->ss0.mag_filter); 50803b705cfSriastradh 50903b705cfSriastradh s_wrap = gen7_repeat_to_string(ss->ss3.s_wrap_mode); 51003b705cfSriastradh t_wrap = gen7_repeat_to_string(ss->ss3.t_wrap_mode); 51103b705cfSriastradh r_wrap = gen7_repeat_to_string(ss->ss3.r_wrap_mode); 51203b705cfSriastradh 51303b705cfSriastradh ErrorF(" Sampler 1:\n"); 51403b705cfSriastradh ErrorF(" filter: min=%s, mag=%s\n", min, mag); 51503b705cfSriastradh ErrorF(" wrap: s=%s, t=%s, r=%s\n", s_wrap, t_wrap, r_wrap); 51603b705cfSriastradh} 51703b705cfSriastradh 51803b705cfSriastradhstatic const char * 51903b705cfSriastradhgen7_blend_factor_to_string(uint32_t v) 52003b705cfSriastradh{ 52103b705cfSriastradh switch (v) { 52203b705cfSriastradh#define C(x) case GEN7_BLENDFACTOR_##x: return #x; 52303b705cfSriastradh C(ONE); 52403b705cfSriastradh C(SRC_COLOR); 52503b705cfSriastradh C(SRC_ALPHA); 52603b705cfSriastradh C(DST_ALPHA); 52703b705cfSriastradh C(DST_COLOR); 52803b705cfSriastradh C(SRC_ALPHA_SATURATE); 52903b705cfSriastradh C(CONST_COLOR); 53003b705cfSriastradh C(CONST_ALPHA); 53103b705cfSriastradh C(SRC1_COLOR); 53203b705cfSriastradh C(SRC1_ALPHA); 53303b705cfSriastradh C(ZERO); 53403b705cfSriastradh C(INV_SRC_COLOR); 53503b705cfSriastradh C(INV_SRC_ALPHA); 53603b705cfSriastradh C(INV_DST_ALPHA); 53703b705cfSriastradh C(INV_DST_COLOR); 53803b705cfSriastradh C(INV_CONST_COLOR); 53903b705cfSriastradh C(INV_CONST_ALPHA); 54003b705cfSriastradh C(INV_SRC1_COLOR); 54103b705cfSriastradh C(INV_SRC1_ALPHA); 54203b705cfSriastradh#undef C 54303b705cfSriastradh default: return "???"; 54403b705cfSriastradh } 54503b705cfSriastradh} 54603b705cfSriastradh 54703b705cfSriastradhstatic const char * 54803b705cfSriastradhgen7_blend_function_to_string(uint32_t v) 54903b705cfSriastradh{ 55003b705cfSriastradh switch (v) { 55103b705cfSriastradh#define C(x) case GEN7_BLENDFUNCTION_##x: return #x; 55203b705cfSriastradh C(ADD); 55303b705cfSriastradh C(SUBTRACT); 55403b705cfSriastradh C(REVERSE_SUBTRACT); 55503b705cfSriastradh C(MIN); 55603b705cfSriastradh C(MAX); 55703b705cfSriastradh#undef C 55803b705cfSriastradh default: return "???"; 55903b705cfSriastradh } 56003b705cfSriastradh} 56103b705cfSriastradh 56203b705cfSriastradhstatic void 56303b705cfSriastradhgen7_decode_blend(struct kgem *kgem, const uint32_t *reloc) 56403b705cfSriastradh{ 56503b705cfSriastradh const struct gen7_blend_state *blend; 56603b705cfSriastradh struct reloc r; 56703b705cfSriastradh const char *dst, *src; 56803b705cfSriastradh const char *func; 56903b705cfSriastradh 57003b705cfSriastradh blend = get_reloc(kgem, state.dynamic_state.ptr, reloc, &r); 57103b705cfSriastradh 57203b705cfSriastradh dst = gen7_blend_factor_to_string(blend->blend0.dest_blend_factor); 57303b705cfSriastradh src = gen7_blend_factor_to_string(blend->blend0.source_blend_factor); 57403b705cfSriastradh func = gen7_blend_function_to_string(blend->blend0.blend_func); 57503b705cfSriastradh 57603b705cfSriastradh ErrorF(" Blend (%s): function %s, src=%s, dst=%s\n", 57703b705cfSriastradh blend->blend0.blend_enable ? "enabled" : "disabled", 57803b705cfSriastradh func, src, dst); 57903b705cfSriastradh} 58003b705cfSriastradh 58103b705cfSriastradhint kgem_gen7_decode_3d(struct kgem *kgem, uint32_t offset) 58203b705cfSriastradh{ 58303b705cfSriastradh static const struct { 58403b705cfSriastradh uint32_t opcode; 58503b705cfSriastradh int min_len; 58603b705cfSriastradh int max_len; 58703b705cfSriastradh const char *name; 58803b705cfSriastradh } opcodes[] = { 58903b705cfSriastradh { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, 59003b705cfSriastradh { 0x6102, 2, 2 , "STATE_SIP" }, 59103b705cfSriastradh { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, 59203b705cfSriastradh { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, 59303b705cfSriastradh { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, 59403b705cfSriastradh }; 59503b705cfSriastradh uint32_t *data = kgem->batch + offset; 59603b705cfSriastradh uint32_t op; 59703b705cfSriastradh unsigned int len; 59803b705cfSriastradh int i; 59903b705cfSriastradh const char *name; 60003b705cfSriastradh 60103b705cfSriastradh len = (data[0] & 0xff) + 2; 60203b705cfSriastradh op = (data[0] & 0xffff0000) >> 16; 60303b705cfSriastradh switch (op) { 60403b705cfSriastradh case 0x6101: 60503b705cfSriastradh i = 0; 60603b705cfSriastradh kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); 60703b705cfSriastradh assert(len == 10); 60803b705cfSriastradh 60903b705cfSriastradh state_base_out(data, offset, i++, "general"); 61003b705cfSriastradh state_base_out(data, offset, i++, "surface"); 61103b705cfSriastradh state_base_out(data, offset, i++, "dynamic"); 61203b705cfSriastradh state_base_out(data, offset, i++, "indirect"); 61303b705cfSriastradh state_base_out(data, offset, i++, "instruction"); 61403b705cfSriastradh 61503b705cfSriastradh state_max_out(data, offset, i++, "general"); 61603b705cfSriastradh state_max_out(data, offset, i++, "dynamic"); 61703b705cfSriastradh state_max_out(data, offset, i++, "indirect"); 61803b705cfSriastradh state_max_out(data, offset, i++, "instruction"); 61903b705cfSriastradh 62003b705cfSriastradh gen7_update_dynamic_buffer(kgem, offset + 3); 62103b705cfSriastradh 62203b705cfSriastradh return len; 62303b705cfSriastradh 62403b705cfSriastradh case 0x7808: 62503b705cfSriastradh assert((len - 1) % 4 == 0); 62603b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); 62703b705cfSriastradh 62803b705cfSriastradh for (i = 1; i < len;) { 62903b705cfSriastradh gen7_update_vertex_buffer(kgem, data + i); 63003b705cfSriastradh 63103b705cfSriastradh kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", 63203b705cfSriastradh data[i] >> 26, 63303b705cfSriastradh data[i] & (1 << 20) ? "random" : "sequential", 63403b705cfSriastradh data[i] & 0x07ff); 63503b705cfSriastradh i++; 63603b705cfSriastradh kgem_debug_print(data, offset, i++, "buffer address\n"); 63703b705cfSriastradh kgem_debug_print(data, offset, i++, "max index\n"); 63803b705cfSriastradh kgem_debug_print(data, offset, i++, "mbz\n"); 63903b705cfSriastradh } 64003b705cfSriastradh return len; 64103b705cfSriastradh 64203b705cfSriastradh case 0x7809: 64303b705cfSriastradh assert((len + 1) % 2 == 0); 64403b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); 64503b705cfSriastradh 64603b705cfSriastradh for (i = 1; i < len;) { 64703b705cfSriastradh gen7_update_vertex_elements(kgem, (i - 1)/2, data + i); 64803b705cfSriastradh 64903b705cfSriastradh kgem_debug_print(data, offset, i, "buffer %d: %svalid, type 0x%04x, " 65003b705cfSriastradh "src offset 0x%04x bytes\n", 65103b705cfSriastradh data[i] >> 26, 65203b705cfSriastradh data[i] & (1 << 25) ? "" : "in", 65303b705cfSriastradh (data[i] >> 16) & 0x1ff, 65403b705cfSriastradh data[i] & 0x07ff); 65503b705cfSriastradh i++; 65603b705cfSriastradh kgem_debug_print(data, offset, i, "(%s, %s, %s, %s), " 65703b705cfSriastradh "dst offset 0x%02x bytes\n", 65803b705cfSriastradh get_element_component(data[i], 0), 65903b705cfSriastradh get_element_component(data[i], 1), 66003b705cfSriastradh get_element_component(data[i], 2), 66103b705cfSriastradh get_element_component(data[i], 3), 66203b705cfSriastradh (data[i] & 0xff) * 4); 66303b705cfSriastradh i++; 66403b705cfSriastradh } 66503b705cfSriastradh return len; 66603b705cfSriastradh 66703b705cfSriastradh case 0x780a: 66803b705cfSriastradh assert(len == 3); 66903b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); 67003b705cfSriastradh kgem_debug_print(data, offset, 1, "beginning buffer address\n"); 67103b705cfSriastradh kgem_debug_print(data, offset, 2, "ending buffer address\n"); 67203b705cfSriastradh return len; 67303b705cfSriastradh 67403b705cfSriastradh case 0x7b00: 67503b705cfSriastradh assert(len == 7); 67603b705cfSriastradh kgem_debug_print(data, offset, 0, "3DPRIMITIVE\n"); 67703b705cfSriastradh kgem_debug_print(data, offset, 1, "type %s, %s\n", 67803b705cfSriastradh get_prim_type(data[1]), 67903b705cfSriastradh (data[1] & (1 << 15)) ? "random" : "sequential"); 68003b705cfSriastradh kgem_debug_print(data, offset, 2, "vertex count\n"); 68103b705cfSriastradh kgem_debug_print(data, offset, 3, "start vertex\n"); 68203b705cfSriastradh kgem_debug_print(data, offset, 4, "instance count\n"); 68303b705cfSriastradh kgem_debug_print(data, offset, 5, "start instance\n"); 68403b705cfSriastradh kgem_debug_print(data, offset, 6, "index bias\n"); 68503b705cfSriastradh primitive_out(kgem, data); 68603b705cfSriastradh return len; 68703b705cfSriastradh } 68803b705cfSriastradh 68903b705cfSriastradh /* For the rest, just dump the bytes */ 69003b705cfSriastradh name = NULL; 69103b705cfSriastradh for (i = 0; i < ARRAY_SIZE(opcodes); i++) 69203b705cfSriastradh if (op == opcodes[i].opcode) { 69303b705cfSriastradh name = opcodes[i].name; 69403b705cfSriastradh break; 69503b705cfSriastradh } 69603b705cfSriastradh 69703b705cfSriastradh len = (data[0] & 0xff) + 2; 69803b705cfSriastradh if (name == NULL) { 69903b705cfSriastradh kgem_debug_print(data, offset, 0, "unknown\n"); 70003b705cfSriastradh } else { 70103b705cfSriastradh kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); 70203b705cfSriastradh if (opcodes[i].max_len > 1) { 70303b705cfSriastradh assert(len >= opcodes[i].min_len && 70403b705cfSriastradh len <= opcodes[i].max_len); 70503b705cfSriastradh } 70603b705cfSriastradh } 70703b705cfSriastradh for (i = 1; i < len; i++) 70803b705cfSriastradh kgem_debug_print(data, offset, i, "dword %d\n", i); 70903b705cfSriastradh 71003b705cfSriastradh return len; 71103b705cfSriastradh} 71203b705cfSriastradh 71303b705cfSriastradhvoid kgem_gen7_finish_state(struct kgem *kgem) 71403b705cfSriastradh{ 71503b705cfSriastradh finish_state(kgem); 71603b705cfSriastradh} 717