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 3903b705cfSriastradh#include "gen5_render.h" 4003b705cfSriastradh 4103b705cfSriastradh#include "kgem_debug.h" 4203b705cfSriastradh 4303b705cfSriastradhstatic struct state { 4403b705cfSriastradh struct vertex_buffer { 4503b705cfSriastradh int handle; 4603b705cfSriastradh void *base; 4703b705cfSriastradh int size; 4803b705cfSriastradh const char *ptr; 4903b705cfSriastradh int pitch; 5003b705cfSriastradh 5103b705cfSriastradh struct kgem_bo *current; 5203b705cfSriastradh } vb[17]; 5303b705cfSriastradh struct vertex_elements { 5403b705cfSriastradh int buffer; 5503b705cfSriastradh int offset; 5603b705cfSriastradh bool valid; 5703b705cfSriastradh uint32_t type; 5803b705cfSriastradh uint8_t swizzle[4]; 5903b705cfSriastradh } ve[17]; 6003b705cfSriastradh int num_ve; 6103b705cfSriastradh 6203b705cfSriastradh struct dynamic_state { 6303b705cfSriastradh struct kgem_bo *current; 6403b705cfSriastradh void *base, *ptr; 6503b705cfSriastradh } dynamic_state; 6603b705cfSriastradh} state; 6703b705cfSriastradh 6803b705cfSriastradhstatic void gen5_update_vertex_buffer(struct kgem *kgem, const uint32_t *data) 6903b705cfSriastradh{ 7003b705cfSriastradh struct drm_i915_gem_relocation_entry *reloc; 7103b705cfSriastradh struct kgem_bo *bo = NULL; 7203b705cfSriastradh void *base, *ptr; 7303b705cfSriastradh int i, size; 7403b705cfSriastradh 7503b705cfSriastradh reloc = kgem_debug_get_reloc_entry(kgem, &data[1] - kgem->batch); 7603b705cfSriastradh if (reloc->target_handle == -1) { 7703b705cfSriastradh base = kgem->batch; 7803b705cfSriastradh size = kgem->nbatch * sizeof(uint32_t); 7903b705cfSriastradh } else { 8003b705cfSriastradh bo = kgem_debug_get_bo_for_reloc_entry(kgem, reloc); 8103b705cfSriastradh base = kgem_bo_map__debug(kgem, bo); 8203b705cfSriastradh size = kgem_bo_size(bo); 8303b705cfSriastradh } 8403b705cfSriastradh ptr = (char *)base + reloc->delta; 8503b705cfSriastradh 8603b705cfSriastradh i = data[0] >> 27; 8703b705cfSriastradh 8803b705cfSriastradh state.vb[i].handle = reloc->target_handle; 8903b705cfSriastradh state.vb[i].current = bo; 9003b705cfSriastradh state.vb[i].base = base; 9103b705cfSriastradh state.vb[i].ptr = ptr; 9203b705cfSriastradh state.vb[i].pitch = data[0] & 0x7ff; 9303b705cfSriastradh state.vb[i].size = size; 9403b705cfSriastradh} 9503b705cfSriastradh 9603b705cfSriastradhstatic uint32_t 9703b705cfSriastradhget_ve_component(uint32_t data, int component) 9803b705cfSriastradh{ 9903b705cfSriastradh return (data >> (16 + (3 - component) * 4)) & 0x7; 10003b705cfSriastradh} 10103b705cfSriastradh 10203b705cfSriastradhstatic void gen5_update_vertex_elements(struct kgem *kgem, int id, const uint32_t *data) 10303b705cfSriastradh{ 10403b705cfSriastradh state.ve[id].buffer = data[0] >> 27; 10503b705cfSriastradh state.ve[id].valid = !!(data[0] & (1 << 26)); 10603b705cfSriastradh state.ve[id].type = (data[0] >> 16) & 0x1ff; 10703b705cfSriastradh state.ve[id].offset = data[0] & 0x7ff; 10803b705cfSriastradh state.ve[id].swizzle[0] = get_ve_component(data[1], 0); 10903b705cfSriastradh state.ve[id].swizzle[1] = get_ve_component(data[1], 1); 11003b705cfSriastradh state.ve[id].swizzle[2] = get_ve_component(data[1], 2); 11103b705cfSriastradh state.ve[id].swizzle[3] = get_ve_component(data[1], 3); 11203b705cfSriastradh} 11303b705cfSriastradh 11403b705cfSriastradhstatic void vertices_sint16_out(const struct vertex_elements *ve, const int16_t *v, int max) 11503b705cfSriastradh{ 11603b705cfSriastradh int c, o; 11703b705cfSriastradh 11803b705cfSriastradh ErrorF("("); 11903b705cfSriastradh for (c = o = 0; c < 4 && o < max; c++) { 12003b705cfSriastradh switch (ve->swizzle[c]) { 12103b705cfSriastradh case 0: ErrorF("#"); break; 12203b705cfSriastradh case 1: ErrorF("%d", v[o++]); break; 12303b705cfSriastradh case 2: ErrorF("0.0"); break; 12403b705cfSriastradh case 3: ErrorF("1.0"); break; 12503b705cfSriastradh case 4: ErrorF("0x1"); break; 12603b705cfSriastradh case 5: break; 12703b705cfSriastradh default: ErrorF("?"); 12803b705cfSriastradh } 12903b705cfSriastradh if (o < max) 13003b705cfSriastradh ErrorF(", "); 13103b705cfSriastradh } 13203b705cfSriastradh ErrorF(")"); 13303b705cfSriastradh} 13403b705cfSriastradh 13503b705cfSriastradhstatic void vertices_float_out(const struct vertex_elements *ve, const float *f, int max) 13603b705cfSriastradh{ 13703b705cfSriastradh int c, o; 13803b705cfSriastradh 13903b705cfSriastradh ErrorF("("); 14003b705cfSriastradh for (c = o = 0; c < 4 && o < max; c++) { 14103b705cfSriastradh switch (ve->swizzle[c]) { 14203b705cfSriastradh case 0: ErrorF("#"); break; 14303b705cfSriastradh case 1: ErrorF("%f", f[o++]); break; 14403b705cfSriastradh case 2: ErrorF("0.0"); break; 14503b705cfSriastradh case 3: ErrorF("1.0"); break; 14603b705cfSriastradh case 4: ErrorF("0x1"); break; 14703b705cfSriastradh case 5: break; 14803b705cfSriastradh default: ErrorF("?"); 14903b705cfSriastradh } 15003b705cfSriastradh if (o < max) 15103b705cfSriastradh ErrorF(", "); 15203b705cfSriastradh } 15303b705cfSriastradh ErrorF(")"); 15403b705cfSriastradh} 15503b705cfSriastradh 15603b705cfSriastradhstatic void ve_out(const struct vertex_elements *ve, const void *ptr) 15703b705cfSriastradh{ 15803b705cfSriastradh switch (ve->type) { 15903b705cfSriastradh case GEN5_SURFACEFORMAT_R32_FLOAT: 16003b705cfSriastradh vertices_float_out(ve, ptr, 1); 16103b705cfSriastradh break; 16203b705cfSriastradh case GEN5_SURFACEFORMAT_R32G32_FLOAT: 16303b705cfSriastradh vertices_float_out(ve, ptr, 2); 16403b705cfSriastradh break; 16503b705cfSriastradh case GEN5_SURFACEFORMAT_R32G32B32_FLOAT: 16603b705cfSriastradh vertices_float_out(ve, ptr, 3); 16703b705cfSriastradh break; 16803b705cfSriastradh case GEN5_SURFACEFORMAT_R32G32B32A32_FLOAT: 16903b705cfSriastradh vertices_float_out(ve, ptr, 4); 17003b705cfSriastradh break; 17103b705cfSriastradh case GEN5_SURFACEFORMAT_R16_SINT: 17203b705cfSriastradh vertices_sint16_out(ve, ptr, 1); 17303b705cfSriastradh break; 17403b705cfSriastradh case GEN5_SURFACEFORMAT_R16G16_SINT: 17503b705cfSriastradh vertices_sint16_out(ve, ptr, 2); 17603b705cfSriastradh break; 17703b705cfSriastradh case GEN5_SURFACEFORMAT_R16G16B16A16_SINT: 17803b705cfSriastradh vertices_sint16_out(ve, ptr, 4); 17903b705cfSriastradh break; 18003b705cfSriastradh case GEN5_SURFACEFORMAT_R16_SSCALED: 18103b705cfSriastradh vertices_sint16_out(ve, ptr, 1); 18203b705cfSriastradh break; 18303b705cfSriastradh case GEN5_SURFACEFORMAT_R16G16_SSCALED: 18403b705cfSriastradh vertices_sint16_out(ve, ptr, 2); 18503b705cfSriastradh break; 18603b705cfSriastradh case GEN5_SURFACEFORMAT_R16G16B16A16_SSCALED: 18703b705cfSriastradh vertices_sint16_out(ve, ptr, 4); 18803b705cfSriastradh break; 18903b705cfSriastradh } 19003b705cfSriastradh} 19103b705cfSriastradh 19203b705cfSriastradhstatic void indirect_vertex_out(struct kgem *kgem, uint32_t v) 19303b705cfSriastradh{ 19403b705cfSriastradh int i = 1; 19503b705cfSriastradh 19603b705cfSriastradh do { 19703b705cfSriastradh const struct vertex_elements *ve = &state.ve[i]; 19803b705cfSriastradh const struct vertex_buffer *vb = &state.vb[ve->buffer]; 19903b705cfSriastradh const void *ptr = vb->ptr + v * vb->pitch + ve->offset; 20003b705cfSriastradh 20103b705cfSriastradh if (!ve->valid) 20203b705cfSriastradh continue; 20303b705cfSriastradh 20403b705cfSriastradh assert(vb->pitch); 20503b705cfSriastradh assert(ve->offset + v*vb->pitch < vb->size); 20603b705cfSriastradh 20703b705cfSriastradh ve_out(ve, ptr); 20803b705cfSriastradh 20903b705cfSriastradh while (++i <= state.num_ve && !state.ve[i].valid) 21003b705cfSriastradh ; 21103b705cfSriastradh 21203b705cfSriastradh if (i <= state.num_ve) 21303b705cfSriastradh ErrorF(", "); 21403b705cfSriastradh } while (i <= state.num_ve); 21503b705cfSriastradh} 21603b705cfSriastradh 21703b705cfSriastradhstatic void primitive_out(struct kgem *kgem, uint32_t *data) 21803b705cfSriastradh{ 21903b705cfSriastradh int n; 22003b705cfSriastradh 22103b705cfSriastradh assert((data[0] & (1<<15)) == 0); /* XXX index buffers */ 22203b705cfSriastradh 22303b705cfSriastradh for (n = 0; n < data[1]; n++) { 22403b705cfSriastradh int v = data[2] + n; 22503b705cfSriastradh ErrorF(" [%d:%d] = ", n, v); 22603b705cfSriastradh indirect_vertex_out(kgem, v); 22703b705cfSriastradh ErrorF("\n"); 22803b705cfSriastradh } 22903b705cfSriastradh} 23003b705cfSriastradh 23103b705cfSriastradhstatic void 23203b705cfSriastradhstate_base_out(uint32_t *data, uint32_t offset, unsigned int index, 23303b705cfSriastradh const char *name) 23403b705cfSriastradh{ 23503b705cfSriastradh if (data[index] & 1) 23603b705cfSriastradh kgem_debug_print(data, offset, index, 23703b705cfSriastradh "%s state base address 0x%08x\n", 23803b705cfSriastradh name, data[index] & ~1); 23903b705cfSriastradh else 24003b705cfSriastradh kgem_debug_print(data, offset, index, 24103b705cfSriastradh "%s state base not updated\n", 24203b705cfSriastradh name); 24303b705cfSriastradh} 24403b705cfSriastradh 24503b705cfSriastradhstatic void 24603b705cfSriastradhstate_max_out(uint32_t *data, uint32_t offset, unsigned int index, 24703b705cfSriastradh const char *name) 24803b705cfSriastradh{ 24903b705cfSriastradh if (data[index] == 1) 25003b705cfSriastradh kgem_debug_print(data, offset, index, 25103b705cfSriastradh "%s state upper bound disabled\n", name); 25203b705cfSriastradh else if (data[index] & 1) 25303b705cfSriastradh kgem_debug_print(data, offset, index, 25403b705cfSriastradh "%s state upper bound 0x%08x\n", 25503b705cfSriastradh name, data[index] & ~1); 25603b705cfSriastradh else 25703b705cfSriastradh kgem_debug_print(data, offset, index, 25803b705cfSriastradh "%s state upper bound not updated\n", 25903b705cfSriastradh name); 26003b705cfSriastradh} 26103b705cfSriastradh 26203b705cfSriastradhstatic const char * 26303b705cfSriastradhget_965_surfacetype(unsigned int surfacetype) 26403b705cfSriastradh{ 26503b705cfSriastradh switch (surfacetype) { 26603b705cfSriastradh case 0: return "1D"; 26703b705cfSriastradh case 1: return "2D"; 26803b705cfSriastradh case 2: return "3D"; 26903b705cfSriastradh case 3: return "CUBE"; 27003b705cfSriastradh case 4: return "BUFFER"; 27103b705cfSriastradh case 7: return "NULL"; 27203b705cfSriastradh default: return "unknown"; 27303b705cfSriastradh } 27403b705cfSriastradh} 27503b705cfSriastradh 27603b705cfSriastradhstatic const char * 27703b705cfSriastradhget_965_depthformat(unsigned int depthformat) 27803b705cfSriastradh{ 27903b705cfSriastradh switch (depthformat) { 28003b705cfSriastradh case 0: return "s8_z24float"; 28103b705cfSriastradh case 1: return "z32float"; 28203b705cfSriastradh case 2: return "z24s8"; 28303b705cfSriastradh case 5: return "z16"; 28403b705cfSriastradh default: return "unknown"; 28503b705cfSriastradh } 28603b705cfSriastradh} 28703b705cfSriastradh 28803b705cfSriastradhstatic const char * 28903b705cfSriastradhget_965_element_component(uint32_t data, int component) 29003b705cfSriastradh{ 29103b705cfSriastradh uint32_t component_control = (data >> (16 + (3 - component) * 4)) & 0x7; 29203b705cfSriastradh 29303b705cfSriastradh switch (component_control) { 29403b705cfSriastradh case 0: 29503b705cfSriastradh return "nostore"; 29603b705cfSriastradh case 1: 29703b705cfSriastradh switch (component) { 29803b705cfSriastradh case 0: return "X"; 29903b705cfSriastradh case 1: return "Y"; 30003b705cfSriastradh case 2: return "Z"; 30103b705cfSriastradh case 3: return "W"; 30203b705cfSriastradh default: return "fail"; 30303b705cfSriastradh } 30403b705cfSriastradh case 2: 30503b705cfSriastradh return "0.0"; 30603b705cfSriastradh case 3: 30703b705cfSriastradh return "1.0"; 30803b705cfSriastradh case 4: 30903b705cfSriastradh return "0x1"; 31003b705cfSriastradh case 5: 31103b705cfSriastradh return "VID"; 31203b705cfSriastradh default: 31303b705cfSriastradh return "fail"; 31403b705cfSriastradh } 31503b705cfSriastradh} 31603b705cfSriastradh 31703b705cfSriastradhstatic const char * 31803b705cfSriastradhget_965_prim_type(uint32_t data) 31903b705cfSriastradh{ 32003b705cfSriastradh uint32_t primtype = (data >> 10) & 0x1f; 32103b705cfSriastradh 32203b705cfSriastradh switch (primtype) { 32303b705cfSriastradh case 0x01: return "point list"; 32403b705cfSriastradh case 0x02: return "line list"; 32503b705cfSriastradh case 0x03: return "line strip"; 32603b705cfSriastradh case 0x04: return "tri list"; 32703b705cfSriastradh case 0x05: return "tri strip"; 32803b705cfSriastradh case 0x06: return "tri fan"; 32903b705cfSriastradh case 0x07: return "quad list"; 33003b705cfSriastradh case 0x08: return "quad strip"; 33103b705cfSriastradh case 0x09: return "line list adj"; 33203b705cfSriastradh case 0x0a: return "line strip adj"; 33303b705cfSriastradh case 0x0b: return "tri list adj"; 33403b705cfSriastradh case 0x0c: return "tri strip adj"; 33503b705cfSriastradh case 0x0d: return "tri strip reverse"; 33603b705cfSriastradh case 0x0e: return "polygon"; 33703b705cfSriastradh case 0x0f: return "rect list"; 33803b705cfSriastradh case 0x10: return "line loop"; 33903b705cfSriastradh case 0x11: return "point list bf"; 34003b705cfSriastradh case 0x12: return "line strip cont"; 34103b705cfSriastradh case 0x13: return "line strip bf"; 34203b705cfSriastradh case 0x14: return "line strip cont bf"; 34303b705cfSriastradh case 0x15: return "tri fan no stipple"; 34403b705cfSriastradh default: return "fail"; 34503b705cfSriastradh } 34603b705cfSriastradh} 34703b705cfSriastradh 34803b705cfSriastradh#if 0 34903b705cfSriastradhstruct reloc { 35003b705cfSriastradh struct kgem_bo *bo; 35103b705cfSriastradh void *base; 35203b705cfSriastradh}; 35303b705cfSriastradh 35403b705cfSriastradhstatic void * 35503b705cfSriastradhget_reloc(struct kgem *kgem, 35603b705cfSriastradh void *base, const uint32_t *reloc, 35703b705cfSriastradh struct reloc *r) 35803b705cfSriastradh{ 35903b705cfSriastradh uint32_t delta = *reloc; 36003b705cfSriastradh 36103b705cfSriastradh memset(r, 0, sizeof(*r)); 36203b705cfSriastradh 36303b705cfSriastradh if (base == 0) { 36403b705cfSriastradh uint32_t handle = sizeof(uint32_t) * (reloc - kgem->batch); 36503b705cfSriastradh struct kgem_bo *bo = NULL; 36603b705cfSriastradh int i; 36703b705cfSriastradh 36803b705cfSriastradh for (i = 0; i < kgem->nreloc; i++) 36903b705cfSriastradh if (kgem->reloc[i].offset == handle) 37003b705cfSriastradh break; 37103b705cfSriastradh assert(i < kgem->nreloc); 37203b705cfSriastradh handle = kgem->reloc[i].target_handle; 37303b705cfSriastradh delta = kgem->reloc[i].delta; 37403b705cfSriastradh 37503b705cfSriastradh if (handle == 0) { 37603b705cfSriastradh base = kgem->batch; 37703b705cfSriastradh } else { 37803b705cfSriastradh list_for_each_entry(bo, &kgem->next_request->buffers, request) 37903b705cfSriastradh if (bo->handle == handle) 38003b705cfSriastradh break; 38103b705cfSriastradh assert(&bo->request != &kgem->next_request->buffers); 38203b705cfSriastradh base = kgem_bo_map(kgem, bo, PROT_READ); 38303b705cfSriastradh r->bo = bo; 38403b705cfSriastradh r->base = base; 38503b705cfSriastradh } 38603b705cfSriastradh } 38703b705cfSriastradh 38803b705cfSriastradh return (char *)base + delta; 38903b705cfSriastradh} 39003b705cfSriastradh#endif 39103b705cfSriastradh 39203b705cfSriastradhint kgem_gen5_decode_3d(struct kgem *kgem, uint32_t offset) 39303b705cfSriastradh{ 39403b705cfSriastradh static const struct { 39503b705cfSriastradh uint32_t opcode; 39603b705cfSriastradh int min_len; 39703b705cfSriastradh int max_len; 39803b705cfSriastradh const char *name; 39903b705cfSriastradh } opcodes[] = { 40003b705cfSriastradh { 0x6000, 3, 3, "URB_FENCE" }, 40103b705cfSriastradh { 0x6001, 2, 2, "CS_URB_FENCE" }, 40203b705cfSriastradh { 0x6002, 2, 2, "CONSTANT_BUFFER" }, 40303b705cfSriastradh { 0x6101, 6, 6, "STATE_BASE_ADDRESS" }, 40403b705cfSriastradh { 0x6102, 2, 2 , "STATE_SIP" }, 40503b705cfSriastradh { 0x6104, 1, 1, "3DSTATE_PIPELINE_SELECT" }, 40603b705cfSriastradh { 0x680b, 1, 1, "3DSTATE_VF_STATISTICS" }, 40703b705cfSriastradh { 0x6904, 1, 1, "3DSTATE_PIPELINE_SELECT" }, 40803b705cfSriastradh { 0x7800, 7, 7, "3DSTATE_PIPELINED_POINTERS" }, 40903b705cfSriastradh { 0x7801, 6, 6, "3DSTATE_BINDING_TABLE_POINTERS" }, 41003b705cfSriastradh { 0x7808, 5, 257, "3DSTATE_VERTEX_BUFFERS" }, 41103b705cfSriastradh { 0x7809, 3, 256, "3DSTATE_VERTEX_ELEMENTS" }, 41203b705cfSriastradh { 0x780a, 3, 3, "3DSTATE_INDEX_BUFFER" }, 41303b705cfSriastradh { 0x780b, 1, 1, "3DSTATE_VF_STATISTICS" }, 41403b705cfSriastradh { 0x7900, 4, 4, "3DSTATE_DRAWING_RECTANGLE" }, 41503b705cfSriastradh { 0x7901, 5, 5, "3DSTATE_CONSTANT_COLOR" }, 41603b705cfSriastradh { 0x7905, 5, 7, "3DSTATE_DEPTH_BUFFER" }, 41703b705cfSriastradh { 0x7906, 2, 2, "3DSTATE_POLY_STIPPLE_OFFSET" }, 41803b705cfSriastradh { 0x7907, 33, 33, "3DSTATE_POLY_STIPPLE_PATTERN" }, 41903b705cfSriastradh { 0x7908, 3, 3, "3DSTATE_LINE_STIPPLE" }, 42003b705cfSriastradh { 0x7909, 2, 2, "3DSTATE_GLOBAL_DEPTH_OFFSET_CLAMP" }, 42103b705cfSriastradh { 0x7909, 2, 2, "3DSTATE_CLEAR_PARAMS" }, 42203b705cfSriastradh { 0x790a, 3, 3, "3DSTATE_AA_LINE_PARAMETERS" }, 42303b705cfSriastradh { 0x790b, 4, 4, "3DSTATE_GS_SVB_INDEX" }, 42403b705cfSriastradh { 0x790d, 3, 3, "3DSTATE_MULTISAMPLE" }, 42503b705cfSriastradh { 0x7910, 2, 2, "3DSTATE_CLEAR_PARAMS" }, 42603b705cfSriastradh { 0x7b00, 6, 6, "3DPRIMITIVE" }, 42703b705cfSriastradh { 0x7805, 3, 3, "3DSTATE_URB" }, 42803b705cfSriastradh { 0x7815, 5, 5, "3DSTATE_CONSTANT_VS_STATE" }, 42903b705cfSriastradh { 0x7816, 5, 5, "3DSTATE_CONSTANT_GS_STATE" }, 43003b705cfSriastradh { 0x7817, 5, 5, "3DSTATE_CONSTANT_PS_STATE" }, 43103b705cfSriastradh { 0x7818, 2, 2, "3DSTATE_SAMPLE_MASK" }, 43203b705cfSriastradh }; 43303b705cfSriastradh uint32_t *data = kgem->batch + offset; 43403b705cfSriastradh uint32_t op; 43503b705cfSriastradh unsigned int len; 43603b705cfSriastradh int i; 43703b705cfSriastradh const char *desc1 = NULL; 43803b705cfSriastradh 43903b705cfSriastradh len = (data[0] & 0xff) + 2; 44003b705cfSriastradh op = (data[0] & 0xffff0000) >> 16; 44103b705cfSriastradh switch (op) { 44203b705cfSriastradh case 0x6000: 44303b705cfSriastradh assert(len == 3); 44403b705cfSriastradh 44503b705cfSriastradh kgem_debug_print(data, offset, 0, "URB_FENCE: %s%s%s%s%s%s\n", 44603b705cfSriastradh (data[0] >> 13) & 1 ? "cs " : "", 44703b705cfSriastradh (data[0] >> 12) & 1 ? "vfe " : "", 44803b705cfSriastradh (data[0] >> 11) & 1 ? "sf " : "", 44903b705cfSriastradh (data[0] >> 10) & 1 ? "clip " : "", 45003b705cfSriastradh (data[0] >> 9) & 1 ? "gs " : "", 45103b705cfSriastradh (data[0] >> 8) & 1 ? "vs " : ""); 45203b705cfSriastradh kgem_debug_print(data, offset, 1, 45303b705cfSriastradh "vs fence: %d, gs_fence: %d, clip_fence: %d\n", 45403b705cfSriastradh data[1] & 0x3ff, 45503b705cfSriastradh (data[1] >> 10) & 0x3ff, 45603b705cfSriastradh (data[1] >> 20) & 0x3ff); 45703b705cfSriastradh kgem_debug_print(data, offset, 2, 45803b705cfSriastradh "sf fence: %d, vfe_fence: %d, cs_fence: %d\n", 45903b705cfSriastradh data[2] & 0x3ff, 46003b705cfSriastradh (data[2] >> 10) & 0x3ff, 46103b705cfSriastradh (data[2] >> 20) & 0x7ff); 46203b705cfSriastradh return len; 46303b705cfSriastradh 46403b705cfSriastradh case 0x6001: 46503b705cfSriastradh kgem_debug_print(data, offset, 0, "CS_URB_STATE\n"); 46603b705cfSriastradh kgem_debug_print(data, offset, 1, "entry_size: %d [%d bytes], n_entries: %d\n", 46703b705cfSriastradh (data[1] >> 4) & 0x1f, 46803b705cfSriastradh (((data[1] >> 4) & 0x1f) + 1) * 64, 46903b705cfSriastradh data[1] & 0x7); 47003b705cfSriastradh return len; 47103b705cfSriastradh case 0x6002: 47203b705cfSriastradh kgem_debug_print(data, offset, 0, "CONSTANT_BUFFER: %s\n", 47303b705cfSriastradh (data[0] >> 8) & 1 ? "valid" : "invalid"); 47403b705cfSriastradh kgem_debug_print(data, offset, 1, "offset: 0x%08x, length: %d bytes\n", 47503b705cfSriastradh data[1] & ~0x3f, ((data[1] & 0x3f) + 1) * 64); 47603b705cfSriastradh return len; 47703b705cfSriastradh case 0x6101: 47803b705cfSriastradh i = 0; 47903b705cfSriastradh kgem_debug_print(data, offset, i++, "STATE_BASE_ADDRESS\n"); 48003b705cfSriastradh assert(len == 8); 48103b705cfSriastradh 48203b705cfSriastradh state_base_out(data, offset, i++, "general"); 48303b705cfSriastradh state_base_out(data, offset, i++, "surface"); 48403b705cfSriastradh state_base_out(data, offset, i++, "media"); 48503b705cfSriastradh state_base_out(data, offset, i++, "instruction"); 48603b705cfSriastradh 48703b705cfSriastradh state_max_out(data, offset, i++, "general"); 48803b705cfSriastradh state_max_out(data, offset, i++, "media"); 48903b705cfSriastradh state_max_out(data, offset, i++, "instruction"); 49003b705cfSriastradh 49103b705cfSriastradh return len; 49203b705cfSriastradh 49303b705cfSriastradh case 0x7801: 49403b705cfSriastradh assert(len == 6); 49503b705cfSriastradh 49603b705cfSriastradh kgem_debug_print(data, offset, 0, 49703b705cfSriastradh "3DSTATE_BINDING_TABLE_POINTERS\n"); 49803b705cfSriastradh kgem_debug_print(data, offset, 1, "VS binding table\n"); 49903b705cfSriastradh kgem_debug_print(data, offset, 2, "GS binding table\n"); 50003b705cfSriastradh kgem_debug_print(data, offset, 3, "CLIP binding table\n"); 50103b705cfSriastradh kgem_debug_print(data, offset, 4, "SF binding table\n"); 50203b705cfSriastradh kgem_debug_print(data, offset, 5, "WM binding table\n"); 50303b705cfSriastradh 50403b705cfSriastradh return len; 50503b705cfSriastradh 50603b705cfSriastradh case 0x7808: 50703b705cfSriastradh assert((len - 1) % 4 == 0); 50803b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_BUFFERS\n"); 50903b705cfSriastradh 51003b705cfSriastradh for (i = 1; i < len;) { 51103b705cfSriastradh gen5_update_vertex_buffer(kgem, data + i); 51203b705cfSriastradh 51303b705cfSriastradh kgem_debug_print(data, offset, i, "buffer %d: %s, pitch %db\n", 51403b705cfSriastradh data[i] >> 27, 51503b705cfSriastradh data[i] & (1 << 20) ? "random" : "sequential", 51603b705cfSriastradh data[i] & 0x07ff); 51703b705cfSriastradh i++; 51803b705cfSriastradh kgem_debug_print(data, offset, i++, "buffer address\n"); 51903b705cfSriastradh kgem_debug_print(data, offset, i++, "max index\n"); 52003b705cfSriastradh kgem_debug_print(data, offset, i++, "mbz\n"); 52103b705cfSriastradh } 52203b705cfSriastradh return len; 52303b705cfSriastradh 52403b705cfSriastradh case 0x7809: 52503b705cfSriastradh assert((len + 1) % 2 == 0); 52603b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_VERTEX_ELEMENTS\n"); 52703b705cfSriastradh 52803b705cfSriastradh memset(state.ve, 0, sizeof(state.ve)); /* XXX? */ 52903b705cfSriastradh for (i = 1; i < len;) { 53003b705cfSriastradh gen5_update_vertex_elements(kgem, (i - 1)/2, data + i); 53103b705cfSriastradh 53203b705cfSriastradh kgem_debug_print(data, offset, i, 53303b705cfSriastradh "buffer %d: %svalid, type 0x%04x, " 53403b705cfSriastradh "src offset 0x%04x bytes\n", 53503b705cfSriastradh data[i] >> 27, 53603b705cfSriastradh data[i] & (1 << 26) ? "" : "in", 53703b705cfSriastradh (data[i] >> 16) & 0x1ff, 53803b705cfSriastradh data[i] & 0x07ff); 53903b705cfSriastradh i++; 54003b705cfSriastradh kgem_debug_print(data, offset, i, "(%s, %s, %s, %s)\n", 54103b705cfSriastradh get_965_element_component(data[i], 0), 54203b705cfSriastradh get_965_element_component(data[i], 1), 54303b705cfSriastradh get_965_element_component(data[i], 2), 54403b705cfSriastradh get_965_element_component(data[i], 3)); 54503b705cfSriastradh i++; 54603b705cfSriastradh } 54703b705cfSriastradh state.num_ve = (len - 1) / 2; /* XXX? */ 54803b705cfSriastradh return len; 54903b705cfSriastradh 55003b705cfSriastradh case 0x780a: 55103b705cfSriastradh assert(len == 3); 55203b705cfSriastradh kgem_debug_print(data, offset, 0, "3DSTATE_INDEX_BUFFER\n"); 55303b705cfSriastradh kgem_debug_print(data, offset, 1, "beginning buffer address\n"); 55403b705cfSriastradh kgem_debug_print(data, offset, 2, "ending buffer address\n"); 55503b705cfSriastradh return len; 55603b705cfSriastradh 55703b705cfSriastradh case 0x7900: 55803b705cfSriastradh assert(len == 4); 55903b705cfSriastradh kgem_debug_print(data, offset, 0, 56003b705cfSriastradh "3DSTATE_DRAWING_RECTANGLE\n"); 56103b705cfSriastradh kgem_debug_print(data, offset, 1, "top left: %d,%d\n", 56203b705cfSriastradh data[1] & 0xffff, 56303b705cfSriastradh (data[1] >> 16) & 0xffff); 56403b705cfSriastradh kgem_debug_print(data, offset, 2, "bottom right: %d,%d\n", 56503b705cfSriastradh data[2] & 0xffff, 56603b705cfSriastradh (data[2] >> 16) & 0xffff); 56703b705cfSriastradh kgem_debug_print(data, offset, 3, "origin: %d,%d\n", 56803b705cfSriastradh (int)data[3] & 0xffff, 56903b705cfSriastradh ((int)data[3] >> 16) & 0xffff); 57003b705cfSriastradh return len; 57103b705cfSriastradh 57203b705cfSriastradh case 0x7905: 57303b705cfSriastradh assert(len == 7); 57403b705cfSriastradh kgem_debug_print(data, offset, 0, 57503b705cfSriastradh "3DSTATE_DEPTH_BUFFER\n"); 576fe8aea9eSmrg kgem_debug_print(data, offset, 1, "%s, %s, pitch = %d bytes, %stiled, HiZ %d, Separate Stencil %d\n", 57703b705cfSriastradh get_965_surfacetype(data[1] >> 29), 57803b705cfSriastradh get_965_depthformat((data[1] >> 18) & 0x7), 57903b705cfSriastradh (data[1] & 0x0001ffff) + 1, 58003b705cfSriastradh data[1] & (1 << 27) ? "" : "not ", 58103b705cfSriastradh (data[1] & (1 << 22)) != 0, 58203b705cfSriastradh (data[1] & (1 << 21)) != 0); 58303b705cfSriastradh kgem_debug_print(data, offset, 2, "depth offset\n"); 58403b705cfSriastradh kgem_debug_print(data, offset, 3, "%dx%d\n", 58503b705cfSriastradh ((data[3] & 0x0007ffc0) >> 6) + 1, 58603b705cfSriastradh ((data[3] & 0xfff80000) >> 19) + 1); 58703b705cfSriastradh kgem_debug_print(data, offset, 4, "volume depth\n"); 58803b705cfSriastradh kgem_debug_print(data, offset, 5, "\n"); 58903b705cfSriastradh kgem_debug_print(data, offset, 6, "\n"); 59003b705cfSriastradh return len; 59103b705cfSriastradh 59203b705cfSriastradh case 0x7a00: 59303b705cfSriastradh assert(len == 4 || len == 5); 59403b705cfSriastradh switch ((data[1] >> 14) & 0x3) { 59503b705cfSriastradh case 0: desc1 = "no write"; break; 59603b705cfSriastradh case 1: desc1 = "qword write"; break; 59703b705cfSriastradh case 2: desc1 = "PS_DEPTH_COUNT write"; break; 59803b705cfSriastradh case 3: desc1 = "TIMESTAMP write"; break; 59903b705cfSriastradh } 60003b705cfSriastradh kgem_debug_print(data, offset, 0, "PIPE_CONTROL\n"); 60103b705cfSriastradh kgem_debug_print(data, offset, 1, 60203b705cfSriastradh "%s, %scs stall, %stlb invalidate, " 60303b705cfSriastradh "%ssync gfdt, %sdepth stall, %sRC write flush, " 60403b705cfSriastradh "%sinst flush, %sTC flush\n", 60503b705cfSriastradh desc1, 60603b705cfSriastradh data[1] & (1 << 20) ? "" : "no ", 60703b705cfSriastradh data[1] & (1 << 18) ? "" : "no ", 60803b705cfSriastradh data[1] & (1 << 17) ? "" : "no ", 60903b705cfSriastradh data[1] & (1 << 13) ? "" : "no ", 61003b705cfSriastradh data[1] & (1 << 12) ? "" : "no ", 61103b705cfSriastradh data[1] & (1 << 11) ? "" : "no ", 61203b705cfSriastradh data[1] & (1 << 10) ? "" : "no "); 61303b705cfSriastradh if (len == 5) { 61403b705cfSriastradh kgem_debug_print(data, offset, 2, "destination address\n"); 61503b705cfSriastradh kgem_debug_print(data, offset, 3, "immediate dword low\n"); 61603b705cfSriastradh kgem_debug_print(data, offset, 4, "immediate dword high\n"); 61703b705cfSriastradh } else { 61803b705cfSriastradh for (i = 2; i < len; i++) { 61903b705cfSriastradh kgem_debug_print(data, offset, i, "\n"); 62003b705cfSriastradh } 62103b705cfSriastradh } 62203b705cfSriastradh return len; 62303b705cfSriastradh 62403b705cfSriastradh case 0x7b00: 62503b705cfSriastradh assert(len == 6); 62603b705cfSriastradh kgem_debug_print(data, offset, 0, 62703b705cfSriastradh "3DPRIMITIVE: %s %s\n", 62803b705cfSriastradh get_965_prim_type(data[0]), 62903b705cfSriastradh (data[0] & (1 << 15)) ? "random" : "sequential"); 63003b705cfSriastradh kgem_debug_print(data, offset, 1, "vertex count\n"); 63103b705cfSriastradh kgem_debug_print(data, offset, 2, "start vertex\n"); 63203b705cfSriastradh kgem_debug_print(data, offset, 3, "instance count\n"); 63303b705cfSriastradh kgem_debug_print(data, offset, 4, "start instance\n"); 63403b705cfSriastradh kgem_debug_print(data, offset, 5, "index bias\n"); 63503b705cfSriastradh primitive_out(kgem, data); 63603b705cfSriastradh return len; 63703b705cfSriastradh } 63803b705cfSriastradh 63903b705cfSriastradh /* For the rest, just dump the bytes */ 64003b705cfSriastradh for (i = 0; i < ARRAY_SIZE(opcodes); i++) 64103b705cfSriastradh if (op == opcodes[i].opcode) 64203b705cfSriastradh break; 64303b705cfSriastradh 64403b705cfSriastradh assert(i < ARRAY_SIZE(opcodes)); 64503b705cfSriastradh 64603b705cfSriastradh len = 1; 64703b705cfSriastradh kgem_debug_print(data, offset, 0, "%s\n", opcodes[i].name); 64803b705cfSriastradh if (opcodes[i].max_len > 1) { 64903b705cfSriastradh len = (data[0] & 0xff) + 2; 65003b705cfSriastradh assert(len >= opcodes[i].min_len && 65103b705cfSriastradh len <= opcodes[i].max_len); 65203b705cfSriastradh } 65303b705cfSriastradh 65403b705cfSriastradh for (i = 1; i < len; i++) 65503b705cfSriastradh kgem_debug_print(data, offset, i, "dword %d\n", i); 65603b705cfSriastradh 65703b705cfSriastradh return len; 65803b705cfSriastradh} 65903b705cfSriastradh 66003b705cfSriastradhvoid kgem_gen5_finish_state(struct kgem *kgem) 66103b705cfSriastradh{ 66203b705cfSriastradh memset(&state, 0, sizeof(state)); 66303b705cfSriastradh} 664