i965_video.c revision fe8aea9e
103b705cfSriastradh/* 203b705cfSriastradh * Copyright � 2006 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 2003b705cfSriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2103b705cfSriastradh * DEALINGS IN THE SOFTWARE. 2203b705cfSriastradh * 2303b705cfSriastradh * Authors: 2403b705cfSriastradh * Eric Anholt <eric@anholt.net> 2503b705cfSriastradh * Keith Packard <keithp@keithp.com> 2603b705cfSriastradh * 2703b705cfSriastradh */ 2803b705cfSriastradh 2903b705cfSriastradh#ifdef HAVE_CONFIG_H 3003b705cfSriastradh#include "config.h" 3103b705cfSriastradh#endif 3203b705cfSriastradh 3342542f5fSchristos#include "xorg-server.h" 3403b705cfSriastradh#include "xf86.h" 3503b705cfSriastradh#include "xf86_OSproc.h" 3603b705cfSriastradh#include "xf86xv.h" 3703b705cfSriastradh#include "fourcc.h" 3803b705cfSriastradh 3903b705cfSriastradh#include "intel.h" 4013496ba1Ssnj#include "intel_uxa.h" 4103b705cfSriastradh#include "i830_reg.h" 4203b705cfSriastradh#include "i965_reg.h" 4303b705cfSriastradh#include "brw_defines.h" 4403b705cfSriastradh#include "brw_structs.h" 4503b705cfSriastradh#include <string.h> 4603b705cfSriastradh 4703b705cfSriastradh 4803b705cfSriastradh/* Make assert() work. */ 4903b705cfSriastradh#undef NDEBUG 5003b705cfSriastradh#include <assert.h> 5103b705cfSriastradh 5203b705cfSriastradhstatic const uint32_t sip_kernel_static[][4] = { 5303b705cfSriastradh/* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */ 5403b705cfSriastradh {0x00000030, 0x20000108, 0x00001220, 0x00000000}, 5503b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 5603b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 5703b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 5803b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 5903b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 6003b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 6103b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 6203b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 6303b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 6403b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 6503b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 6603b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 6703b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 6803b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 6903b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 7003b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 7103b705cfSriastradh/* nop (4) g0<1>UD { align1 + } */ 7203b705cfSriastradh {0x0040007e, 0x20000c21, 0x00690000, 0x00000000}, 7303b705cfSriastradh}; 7403b705cfSriastradh 7503b705cfSriastradh/* 7603b705cfSriastradh * this program computes dA/dx and dA/dy for the texture coordinates along 7703b705cfSriastradh * with the base texture coordinate. It was extracted from the Mesa driver. 7803b705cfSriastradh * It uses about 10 GRF registers. 7903b705cfSriastradh */ 8003b705cfSriastradh 8103b705cfSriastradh#define SF_KERNEL_NUM_GRF 16 8203b705cfSriastradh#define SF_MAX_THREADS 1 8303b705cfSriastradh 8403b705cfSriastradhstatic const uint32_t sf_kernel_static[][4] = { 8503b705cfSriastradh#include "exa_sf.g4b" 8603b705cfSriastradh}; 8703b705cfSriastradh 8803b705cfSriastradh/* 8903b705cfSriastradh * Ok, this kernel picks up the required data flow values in g0 and g1 9003b705cfSriastradh * and passes those along in m0 and m1. In m2-m9, it sticks constant 9103b705cfSriastradh * values (bright pink). 9203b705cfSriastradh */ 9303b705cfSriastradh 9403b705cfSriastradh/* Our PS kernel uses less than 32 GRF registers (about 20) */ 9503b705cfSriastradh#define PS_KERNEL_NUM_GRF 32 9603b705cfSriastradh#define PS_MAX_THREADS 32 9703b705cfSriastradh 9803b705cfSriastradh#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1) 9903b705cfSriastradh 10003b705cfSriastradhstatic const uint32_t ps_kernel_packed_static[][4] = { 10103b705cfSriastradh#include "exa_wm_xy.g4b" 10203b705cfSriastradh#include "exa_wm_src_affine.g4b" 10303b705cfSriastradh#include "exa_wm_src_sample_argb.g4b" 104fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g4b" 10503b705cfSriastradh#include "exa_wm_write.g4b" 10603b705cfSriastradh}; 10703b705cfSriastradh 10803b705cfSriastradhstatic const uint32_t ps_kernel_planar_static[][4] = { 10903b705cfSriastradh#include "exa_wm_xy.g4b" 11003b705cfSriastradh#include "exa_wm_src_affine.g4b" 11103b705cfSriastradh#include "exa_wm_src_sample_planar.g4b" 112fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g4b" 11303b705cfSriastradh#include "exa_wm_write.g4b" 11403b705cfSriastradh}; 11503b705cfSriastradh 11603b705cfSriastradh/* new program for Ironlake */ 11703b705cfSriastradhstatic const uint32_t sf_kernel_static_gen5[][4] = { 11803b705cfSriastradh#include "exa_sf.g4b.gen5" 11903b705cfSriastradh}; 12003b705cfSriastradh 12103b705cfSriastradhstatic const uint32_t ps_kernel_packed_static_gen5[][4] = { 12203b705cfSriastradh#include "exa_wm_xy.g4b.gen5" 12303b705cfSriastradh#include "exa_wm_src_affine.g4b.gen5" 12403b705cfSriastradh#include "exa_wm_src_sample_argb.g4b.gen5" 125fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g4b.gen5" 12603b705cfSriastradh#include "exa_wm_write.g4b.gen5" 12703b705cfSriastradh}; 12803b705cfSriastradh 12903b705cfSriastradhstatic const uint32_t ps_kernel_planar_static_gen5[][4] = { 13003b705cfSriastradh#include "exa_wm_xy.g4b.gen5" 13103b705cfSriastradh#include "exa_wm_src_affine.g4b.gen5" 13203b705cfSriastradh#include "exa_wm_src_sample_planar.g4b.gen5" 133fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g4b.gen5" 13403b705cfSriastradh#include "exa_wm_write.g4b.gen5" 13503b705cfSriastradh}; 13603b705cfSriastradh 13703b705cfSriastradh/* programs for Sandybridge */ 13803b705cfSriastradhstatic const uint32_t ps_kernel_packed_static_gen6[][4] = { 13903b705cfSriastradh#include "exa_wm_src_affine.g6b" 14003b705cfSriastradh#include "exa_wm_src_sample_argb.g6b" 141fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g6b" 14203b705cfSriastradh#include "exa_wm_write.g6b" 14303b705cfSriastradh}; 14403b705cfSriastradh 14503b705cfSriastradhstatic const uint32_t ps_kernel_planar_static_gen6[][4] = { 14603b705cfSriastradh#include "exa_wm_src_affine.g6b" 14703b705cfSriastradh#include "exa_wm_src_sample_planar.g6b" 148fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g6b" 14903b705cfSriastradh#include "exa_wm_write.g6b" 15003b705cfSriastradh}; 15103b705cfSriastradh 15203b705cfSriastradh/* programs for Ivybridge */ 15303b705cfSriastradhstatic const uint32_t ps_kernel_packed_static_gen7[][4] = { 15403b705cfSriastradh#include "exa_wm_src_affine.g7b" 15503b705cfSriastradh#include "exa_wm_src_sample_argb.g7b" 156fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g7b" 15703b705cfSriastradh#include "exa_wm_write.g7b" 15803b705cfSriastradh}; 15903b705cfSriastradh 16003b705cfSriastradhstatic const uint32_t ps_kernel_planar_static_gen7[][4] = { 16103b705cfSriastradh#include "exa_wm_src_affine.g7b" 16203b705cfSriastradh#include "exa_wm_src_sample_planar.g7b" 163fe8aea9eSmrg#include "exa_wm_yuv_rgb_bt601.g7b" 16403b705cfSriastradh#include "exa_wm_write.g7b" 16503b705cfSriastradh}; 16603b705cfSriastradh 16703b705cfSriastradh#ifndef MAX2 16803b705cfSriastradh#define MAX2(a,b) ((a) > (b) ? (a) : (b)) 16903b705cfSriastradh#endif 17003b705cfSriastradh 17103b705cfSriastradh#define SURFACE_STATE_PADDED_SIZE_I965 ALIGN(sizeof(struct brw_surface_state), 32) 17203b705cfSriastradh#define SURFACE_STATE_PADDED_SIZE_GEN7 ALIGN(sizeof(struct gen7_surface_state), 32) 17303b705cfSriastradh#define SURFACE_STATE_PADDED_SIZE MAX2(SURFACE_STATE_PADDED_SIZE_I965, SURFACE_STATE_PADDED_SIZE_GEN7) 17403b705cfSriastradh#define SURFACE_STATE_OFFSET(index) (SURFACE_STATE_PADDED_SIZE * index) 17503b705cfSriastradh 17603b705cfSriastradhstatic uint32_t float_to_uint(float f) 17703b705cfSriastradh{ 17803b705cfSriastradh union { 17903b705cfSriastradh uint32_t i; 18003b705cfSriastradh float f; 18103b705cfSriastradh } x; 18203b705cfSriastradh x.f = f; 18303b705cfSriastradh return x.i; 18403b705cfSriastradh} 18503b705cfSriastradh 18603b705cfSriastradh#if 0 18703b705cfSriastradhstatic struct { 18803b705cfSriastradh uint32_t svg_ctl; 18903b705cfSriastradh char *name; 19003b705cfSriastradh} svg_ctl_bits[] = { 19103b705cfSriastradh { 19203b705cfSriastradh BRW_SVG_CTL_GS_BA, "General State Base Address"}, { 19303b705cfSriastradh BRW_SVG_CTL_SS_BA, "Surface State Base Address"}, { 19403b705cfSriastradh BRW_SVG_CTL_IO_BA, "Indirect Object Base Address"}, { 19503b705cfSriastradh BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound"}, { 19603b705cfSriastradh BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound"}, { 19703b705cfSriastradh BRW_SVG_CTL_SIP, "System Instruction Pointer"}, { 19803b705cfSriastradh0, 0},}; 19903b705cfSriastradh 20003b705cfSriastradhstatic void brw_debug(ScrnInfoPtr scrn, char *when) 20103b705cfSriastradh{ 20203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 20303b705cfSriastradh int i; 20403b705cfSriastradh uint32_t v; 20503b705cfSriastradh 20603b705cfSriastradh ErrorF("brw_debug: %s\n", when); 20703b705cfSriastradh for (i = 0; svg_ctl_bits[i].name; i++) { 20803b705cfSriastradh OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl); 20903b705cfSriastradh v = INREG(BRW_SVG_RDATA); 21003b705cfSriastradh ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v); 21103b705cfSriastradh } 21203b705cfSriastradh} 21303b705cfSriastradh#endif 21403b705cfSriastradh 21503b705cfSriastradh#define WATCH_SF 0 21603b705cfSriastradh#define WATCH_WIZ 0 21703b705cfSriastradh#define WATCH_STATS 0 21803b705cfSriastradh 21903b705cfSriastradhstatic void i965_pre_draw_debug(ScrnInfoPtr scrn) 22003b705cfSriastradh{ 22103b705cfSriastradh#if 0 22203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 22303b705cfSriastradh#endif 22403b705cfSriastradh 22503b705cfSriastradh#if 0 22603b705cfSriastradh ErrorF("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n", 22703b705cfSriastradh INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0), 22803b705cfSriastradh INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0)); 22903b705cfSriastradh 23003b705cfSriastradh OUTREG(BRW_VF_CTL, 23103b705cfSriastradh BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID | 23203b705cfSriastradh BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX | 23303b705cfSriastradh BRW_VF_CTL_SNAPSHOT_ENABLE); 23403b705cfSriastradh OUTREG(BRW_VF_STRG_VAL, 0); 23503b705cfSriastradh#endif 23603b705cfSriastradh 23703b705cfSriastradh#if 0 23803b705cfSriastradh OUTREG(BRW_VS_CTL, 23903b705cfSriastradh BRW_VS_CTL_SNAPSHOT_ALL_THREADS | 24003b705cfSriastradh BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT | 24103b705cfSriastradh BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE); 24203b705cfSriastradh 24303b705cfSriastradh OUTREG(BRW_VS_STRG_VAL, 0); 24403b705cfSriastradh#endif 24503b705cfSriastradh 24603b705cfSriastradh#if WATCH_SF 24703b705cfSriastradh OUTREG(BRW_SF_CTL, 24803b705cfSriastradh BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT | 24903b705cfSriastradh BRW_SF_CTL_SNAPSHOT_ALL_THREADS | 25003b705cfSriastradh BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE); 25103b705cfSriastradh OUTREG(BRW_SF_STRG_VAL, 0); 25203b705cfSriastradh#endif 25303b705cfSriastradh 25403b705cfSriastradh#if WATCH_WIZ 25503b705cfSriastradh OUTREG(BRW_WIZ_CTL, 25603b705cfSriastradh BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE | 25703b705cfSriastradh BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS | BRW_WIZ_CTL_SNAPSHOT_ENABLE); 25803b705cfSriastradh OUTREG(BRW_WIZ_STRG_VAL, (box_x1) | (box_y1 << 16)); 25903b705cfSriastradh#endif 26003b705cfSriastradh 26103b705cfSriastradh#if 0 26203b705cfSriastradh OUTREG(BRW_TS_CTL, 26303b705cfSriastradh BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR | 26403b705cfSriastradh BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS | 26503b705cfSriastradh BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS | 26603b705cfSriastradh BRW_TS_CTL_SNAPSHOT_ENABLE); 26703b705cfSriastradh#endif 26803b705cfSriastradh} 26903b705cfSriastradh 27003b705cfSriastradhstatic void i965_post_draw_debug(ScrnInfoPtr scrn) 27103b705cfSriastradh{ 27203b705cfSriastradh#if 0 27303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 27403b705cfSriastradh#endif 27503b705cfSriastradh 27603b705cfSriastradh#if 0 27703b705cfSriastradh for (j = 0; j < 100000; j++) { 27803b705cfSriastradh ctl = INREG(BRW_VF_CTL); 27903b705cfSriastradh if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE) 28003b705cfSriastradh break; 28103b705cfSriastradh } 28203b705cfSriastradh 28303b705cfSriastradh rdata = INREG(BRW_VF_RDATA); 28403b705cfSriastradh OUTREG(BRW_VF_CTL, 0); 28503b705cfSriastradh ErrorF("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata); 28603b705cfSriastradh#endif 28703b705cfSriastradh 28803b705cfSriastradh#if 0 28903b705cfSriastradh for (j = 0; j < 1000000; j++) { 29003b705cfSriastradh ctl = INREG(BRW_VS_CTL); 29103b705cfSriastradh if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE) 29203b705cfSriastradh break; 29303b705cfSriastradh } 29403b705cfSriastradh 29503b705cfSriastradh rdata = INREG(BRW_VS_RDATA); 29603b705cfSriastradh for (k = 0; k <= 3; k++) { 29703b705cfSriastradh OUTREG(BRW_VS_CTL, BRW_VS_CTL_SNAPSHOT_COMPLETE | (k << 8)); 29803b705cfSriastradh rdata = INREG(BRW_VS_RDATA); 29903b705cfSriastradh ErrorF("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata); 30003b705cfSriastradh } 30103b705cfSriastradh 30203b705cfSriastradh OUTREG(BRW_VS_CTL, 0); 30303b705cfSriastradh#endif 30403b705cfSriastradh 30503b705cfSriastradh#if WATCH_SF 30603b705cfSriastradh for (j = 0; j < 1000000; j++) { 30703b705cfSriastradh ctl = INREG(BRW_SF_CTL); 30803b705cfSriastradh if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE) 30903b705cfSriastradh break; 31003b705cfSriastradh } 31103b705cfSriastradh 31203b705cfSriastradh for (k = 0; k <= 7; k++) { 31303b705cfSriastradh OUTREG(BRW_SF_CTL, BRW_SF_CTL_SNAPSHOT_COMPLETE | (k << 8)); 31403b705cfSriastradh rdata = INREG(BRW_SF_RDATA); 31503b705cfSriastradh ErrorF("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata); 31603b705cfSriastradh } 31703b705cfSriastradh 31803b705cfSriastradh OUTREG(BRW_SF_CTL, 0); 31903b705cfSriastradh#endif 32003b705cfSriastradh 32103b705cfSriastradh#if WATCH_WIZ 32203b705cfSriastradh for (j = 0; j < 100000; j++) { 32303b705cfSriastradh ctl = INREG(BRW_WIZ_CTL); 32403b705cfSriastradh if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE) 32503b705cfSriastradh break; 32603b705cfSriastradh } 32703b705cfSriastradh 32803b705cfSriastradh rdata = INREG(BRW_WIZ_RDATA); 32903b705cfSriastradh OUTREG(BRW_WIZ_CTL, 0); 33003b705cfSriastradh ErrorF("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata); 33103b705cfSriastradh#endif 33203b705cfSriastradh 33303b705cfSriastradh#if 0 33403b705cfSriastradh for (j = 0; j < 100000; j++) { 33503b705cfSriastradh ctl = INREG(BRW_TS_CTL); 33603b705cfSriastradh if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE) 33703b705cfSriastradh break; 33803b705cfSriastradh } 33903b705cfSriastradh 34003b705cfSriastradh rdata = INREG(BRW_TS_RDATA); 34103b705cfSriastradh OUTREG(BRW_TS_CTL, 0); 34203b705cfSriastradh ErrorF("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata); 34303b705cfSriastradh 34403b705cfSriastradh ErrorF("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n", 34503b705cfSriastradh INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0), 34603b705cfSriastradh INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0)); 34703b705cfSriastradh#endif 34803b705cfSriastradh 34903b705cfSriastradh#if 0 35003b705cfSriastradh for (j = 0; j < 256; j++) { 35103b705cfSriastradh OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT); 35203b705cfSriastradh rdata = INREG(BRW_TD_RDATA); 35303b705cfSriastradh ErrorF("TD_RDATA(%d): 0x%08x\n", j, rdata); 35403b705cfSriastradh } 35503b705cfSriastradh#endif 35603b705cfSriastradh} 35703b705cfSriastradh 35803b705cfSriastradh/* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it. 35903b705cfSriastradh * A VUE consists of a 256-bit vertex header followed by the vertex data, 36003b705cfSriastradh * which in our case is 4 floats (128 bits), thus a single 512-bit URB 36103b705cfSriastradh * entry. 36203b705cfSriastradh */ 36303b705cfSriastradh#define URB_VS_ENTRIES 8 36403b705cfSriastradh#define URB_VS_ENTRY_SIZE 1 36503b705cfSriastradh 36603b705cfSriastradh#define URB_GS_ENTRIES 0 36703b705cfSriastradh#define URB_GS_ENTRY_SIZE 0 36803b705cfSriastradh 36903b705cfSriastradh#define URB_CLIP_ENTRIES 0 37003b705cfSriastradh#define URB_CLIP_ENTRY_SIZE 0 37103b705cfSriastradh 37203b705cfSriastradh/* The SF kernel we use outputs only 4 256-bit registers, leading to an 37303b705cfSriastradh * entry size of 2 512-bit URBs. We don't need to have many entries to 37403b705cfSriastradh * output as we're generally working on large rectangles and don't care 37503b705cfSriastradh * about having WM threads running on different rectangles simultaneously. 37603b705cfSriastradh */ 37703b705cfSriastradh#define URB_SF_ENTRIES 1 37803b705cfSriastradh#define URB_SF_ENTRY_SIZE 2 37903b705cfSriastradh 38003b705cfSriastradh#define URB_CS_ENTRIES 0 38103b705cfSriastradh#define URB_CS_ENTRY_SIZE 0 38203b705cfSriastradh 38303b705cfSriastradhstatic void i965_create_dst_surface_state(ScrnInfoPtr scrn, 38403b705cfSriastradh PixmapPtr pixmap, 38503b705cfSriastradh drm_intel_bo *surf_bo, 38603b705cfSriastradh uint32_t offset) 38703b705cfSriastradh{ 38803b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 38903b705cfSriastradh struct brw_surface_state dest_surf_state; 39013496ba1Ssnj drm_intel_bo *pixmap_bo = intel_uxa_get_pixmap_bo(pixmap); 39103b705cfSriastradh assert(pixmap_bo != NULL); 39203b705cfSriastradh 39303b705cfSriastradh memset(&dest_surf_state, 0, sizeof(dest_surf_state)); 39403b705cfSriastradh 39503b705cfSriastradh dest_surf_state.ss0.surface_type = BRW_SURFACE_2D; 39603b705cfSriastradh dest_surf_state.ss0.data_return_format = 39703b705cfSriastradh BRW_SURFACERETURNFORMAT_FLOAT32; 39803b705cfSriastradh if (intel->cpp == 2) { 39903b705cfSriastradh dest_surf_state.ss0.surface_format = 40003b705cfSriastradh BRW_SURFACEFORMAT_B5G6R5_UNORM; 40103b705cfSriastradh } else { 40203b705cfSriastradh dest_surf_state.ss0.surface_format = 40303b705cfSriastradh BRW_SURFACEFORMAT_B8G8R8A8_UNORM; 40403b705cfSriastradh } 40503b705cfSriastradh dest_surf_state.ss0.writedisable_alpha = 0; 40603b705cfSriastradh dest_surf_state.ss0.writedisable_red = 0; 40703b705cfSriastradh dest_surf_state.ss0.writedisable_green = 0; 40803b705cfSriastradh dest_surf_state.ss0.writedisable_blue = 0; 40903b705cfSriastradh dest_surf_state.ss0.color_blend = 1; 41003b705cfSriastradh dest_surf_state.ss0.vert_line_stride = 0; 41103b705cfSriastradh dest_surf_state.ss0.vert_line_stride_ofs = 0; 41203b705cfSriastradh dest_surf_state.ss0.mipmap_layout_mode = 0; 41303b705cfSriastradh dest_surf_state.ss0.render_cache_read_mode = 0; 41403b705cfSriastradh 41503b705cfSriastradh dest_surf_state.ss1.base_addr = 41613496ba1Ssnj intel_uxa_emit_reloc(surf_bo, offset + offsetof(struct brw_surface_state, ss1), 41703b705cfSriastradh pixmap_bo, 0, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); 41803b705cfSriastradh 41903b705cfSriastradh dest_surf_state.ss2.height = pixmap->drawable.height - 1; 42003b705cfSriastradh dest_surf_state.ss2.width = pixmap->drawable.width - 1; 42103b705cfSriastradh dest_surf_state.ss2.mip_count = 0; 42203b705cfSriastradh dest_surf_state.ss2.render_target_rotation = 0; 42303b705cfSriastradh dest_surf_state.ss3.pitch = intel_pixmap_pitch(pixmap) - 1; 42413496ba1Ssnj dest_surf_state.ss3.tiled_surface = intel_uxa_pixmap_tiled(pixmap); 42503b705cfSriastradh dest_surf_state.ss3.tile_walk = 0; /* TileX */ 42603b705cfSriastradh 42703b705cfSriastradh dri_bo_subdata(surf_bo, 42803b705cfSriastradh offset, sizeof(dest_surf_state), 42903b705cfSriastradh &dest_surf_state); 43003b705cfSriastradh} 43103b705cfSriastradh 43203b705cfSriastradhstatic void i965_create_src_surface_state(ScrnInfoPtr scrn, 43303b705cfSriastradh drm_intel_bo * src_bo, 43403b705cfSriastradh uint32_t src_offset, 43503b705cfSriastradh int src_width, 43603b705cfSriastradh int src_height, 43703b705cfSriastradh int src_pitch, 43803b705cfSriastradh uint32_t src_surf_format, 43903b705cfSriastradh drm_intel_bo *surface_bo, 44003b705cfSriastradh uint32_t offset) 44103b705cfSriastradh{ 44203b705cfSriastradh struct brw_surface_state src_surf_state; 44303b705cfSriastradh 44403b705cfSriastradh memset(&src_surf_state, 0, sizeof(src_surf_state)); 44503b705cfSriastradh 44603b705cfSriastradh /* Set up the source surface state buffer */ 44703b705cfSriastradh src_surf_state.ss0.surface_type = BRW_SURFACE_2D; 44803b705cfSriastradh src_surf_state.ss0.surface_format = src_surf_format; 44903b705cfSriastradh src_surf_state.ss0.writedisable_alpha = 0; 45003b705cfSriastradh src_surf_state.ss0.writedisable_red = 0; 45103b705cfSriastradh src_surf_state.ss0.writedisable_green = 0; 45203b705cfSriastradh src_surf_state.ss0.writedisable_blue = 0; 45303b705cfSriastradh src_surf_state.ss0.color_blend = 1; 45403b705cfSriastradh src_surf_state.ss0.vert_line_stride = 0; 45503b705cfSriastradh src_surf_state.ss0.vert_line_stride_ofs = 0; 45603b705cfSriastradh src_surf_state.ss0.mipmap_layout_mode = 0; 45703b705cfSriastradh src_surf_state.ss0.render_cache_read_mode = 0; 45803b705cfSriastradh 45903b705cfSriastradh src_surf_state.ss2.width = src_width - 1; 46003b705cfSriastradh src_surf_state.ss2.height = src_height - 1; 46103b705cfSriastradh src_surf_state.ss2.mip_count = 0; 46203b705cfSriastradh src_surf_state.ss2.render_target_rotation = 0; 46303b705cfSriastradh src_surf_state.ss3.pitch = src_pitch - 1; 46403b705cfSriastradh 46503b705cfSriastradh if (src_bo) { 46603b705cfSriastradh src_surf_state.ss1.base_addr = 46713496ba1Ssnj intel_uxa_emit_reloc(surface_bo, 46803b705cfSriastradh offset + offsetof(struct brw_surface_state, ss1), 46903b705cfSriastradh src_bo, src_offset, 47003b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 47103b705cfSriastradh } else { 47203b705cfSriastradh src_surf_state.ss1.base_addr = src_offset; 47303b705cfSriastradh } 47403b705cfSriastradh 47503b705cfSriastradh dri_bo_subdata(surface_bo, 47603b705cfSriastradh offset, sizeof(src_surf_state), 47703b705cfSriastradh &src_surf_state); 47803b705cfSriastradh} 47903b705cfSriastradh 48003b705cfSriastradhstatic void gen7_create_dst_surface_state(ScrnInfoPtr scrn, 48103b705cfSriastradh PixmapPtr pixmap, 48203b705cfSriastradh drm_intel_bo *surf_bo, 48303b705cfSriastradh uint32_t offset) 48403b705cfSriastradh{ 48503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 48603b705cfSriastradh struct gen7_surface_state dest_surf_state; 48713496ba1Ssnj drm_intel_bo *pixmap_bo = intel_uxa_get_pixmap_bo(pixmap); 48803b705cfSriastradh assert(pixmap_bo != NULL); 48903b705cfSriastradh 49003b705cfSriastradh memset(&dest_surf_state, 0, sizeof(dest_surf_state)); 49103b705cfSriastradh 49203b705cfSriastradh dest_surf_state.ss0.surface_type = BRW_SURFACE_2D; 49313496ba1Ssnj dest_surf_state.ss0.tiled_surface = intel_uxa_pixmap_tiled(pixmap); 49403b705cfSriastradh dest_surf_state.ss0.tile_walk = 0; /* TileX */ 49503b705cfSriastradh 49603b705cfSriastradh if (intel->cpp == 2) { 49703b705cfSriastradh dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM; 49803b705cfSriastradh } else { 49903b705cfSriastradh dest_surf_state.ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM; 50003b705cfSriastradh } 50103b705cfSriastradh 50203b705cfSriastradh dest_surf_state.ss1.base_addr = 50313496ba1Ssnj intel_uxa_emit_reloc(surf_bo, 50403b705cfSriastradh offset + offsetof(struct gen7_surface_state, ss1), 50503b705cfSriastradh pixmap_bo, 0, 50603b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 50703b705cfSriastradh 50803b705cfSriastradh dest_surf_state.ss2.height = pixmap->drawable.height - 1; 50903b705cfSriastradh dest_surf_state.ss2.width = pixmap->drawable.width - 1; 51003b705cfSriastradh 51103b705cfSriastradh dest_surf_state.ss3.pitch = intel_pixmap_pitch(pixmap) - 1; 51203b705cfSriastradh 51303b705cfSriastradh if (IS_HSW(intel)) { 51403b705cfSriastradh dest_surf_state.ss7.shader_chanel_select_r = HSW_SCS_RED; 51503b705cfSriastradh dest_surf_state.ss7.shader_chanel_select_g = HSW_SCS_GREEN; 51603b705cfSriastradh dest_surf_state.ss7.shader_chanel_select_b = HSW_SCS_BLUE; 51703b705cfSriastradh dest_surf_state.ss7.shader_chanel_select_a = HSW_SCS_ALPHA; 51803b705cfSriastradh } 51903b705cfSriastradh 52003b705cfSriastradh dri_bo_subdata(surf_bo, 52103b705cfSriastradh offset, sizeof(dest_surf_state), 52203b705cfSriastradh &dest_surf_state); 52303b705cfSriastradh} 52403b705cfSriastradh 52503b705cfSriastradhstatic void gen7_create_src_surface_state(ScrnInfoPtr scrn, 52603b705cfSriastradh drm_intel_bo * src_bo, 52703b705cfSriastradh uint32_t src_offset, 52803b705cfSriastradh int src_width, 52903b705cfSriastradh int src_height, 53003b705cfSriastradh int src_pitch, 53103b705cfSriastradh uint32_t src_surf_format, 53203b705cfSriastradh drm_intel_bo *surface_bo, 53303b705cfSriastradh uint32_t offset) 53403b705cfSriastradh{ 53503b705cfSriastradh intel_screen_private * const intel = intel_get_screen_private(scrn); 53603b705cfSriastradh struct gen7_surface_state src_surf_state; 53703b705cfSriastradh 53803b705cfSriastradh memset(&src_surf_state, 0, sizeof(src_surf_state)); 53903b705cfSriastradh 54003b705cfSriastradh src_surf_state.ss0.surface_type = BRW_SURFACE_2D; 54103b705cfSriastradh src_surf_state.ss0.surface_format = src_surf_format; 54203b705cfSriastradh 54303b705cfSriastradh if (src_bo) { 54403b705cfSriastradh src_surf_state.ss1.base_addr = 54513496ba1Ssnj intel_uxa_emit_reloc(surface_bo, 54603b705cfSriastradh offset + offsetof(struct gen7_surface_state, ss1), 54703b705cfSriastradh src_bo, src_offset, 54803b705cfSriastradh I915_GEM_DOMAIN_SAMPLER, 0); 54903b705cfSriastradh } else { 55003b705cfSriastradh src_surf_state.ss1.base_addr = src_offset; 55103b705cfSriastradh } 55203b705cfSriastradh 55303b705cfSriastradh src_surf_state.ss2.width = src_width - 1; 55403b705cfSriastradh src_surf_state.ss2.height = src_height - 1; 55503b705cfSriastradh 55603b705cfSriastradh src_surf_state.ss3.pitch = src_pitch - 1; 55703b705cfSriastradh 55803b705cfSriastradh if (IS_HSW(intel)) { 55903b705cfSriastradh src_surf_state.ss7.shader_chanel_select_r = HSW_SCS_RED; 56003b705cfSriastradh src_surf_state.ss7.shader_chanel_select_g = HSW_SCS_GREEN; 56103b705cfSriastradh src_surf_state.ss7.shader_chanel_select_b = HSW_SCS_BLUE; 56203b705cfSriastradh src_surf_state.ss7.shader_chanel_select_a = HSW_SCS_ALPHA; 56303b705cfSriastradh } 56403b705cfSriastradh 56503b705cfSriastradh dri_bo_subdata(surface_bo, 56603b705cfSriastradh offset, sizeof(src_surf_state), 56703b705cfSriastradh &src_surf_state); 56803b705cfSriastradh} 56903b705cfSriastradh 57003b705cfSriastradhstatic void i965_create_binding_table(ScrnInfoPtr scrn, 57103b705cfSriastradh drm_intel_bo *bind_bo, 57203b705cfSriastradh int n_surf) 57303b705cfSriastradh{ 57403b705cfSriastradh uint32_t binding_table[n_surf]; 57503b705cfSriastradh int i; 57603b705cfSriastradh 57703b705cfSriastradh /* Set up a binding table for our surfaces. Only the PS will use it */ 57803b705cfSriastradh for (i = 0; i < n_surf; i++) 57903b705cfSriastradh binding_table[i] = i * SURFACE_STATE_PADDED_SIZE; 58003b705cfSriastradh 58103b705cfSriastradh dri_bo_subdata(bind_bo, 58203b705cfSriastradh n_surf * SURFACE_STATE_PADDED_SIZE, 58303b705cfSriastradh sizeof(binding_table), binding_table); 58403b705cfSriastradh} 58503b705cfSriastradh 58603b705cfSriastradhstatic drm_intel_bo *i965_create_sampler_state(ScrnInfoPtr scrn) 58703b705cfSriastradh{ 58803b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 58903b705cfSriastradh struct brw_sampler_state sampler_state; 59003b705cfSriastradh 59103b705cfSriastradh memset(&sampler_state, 0, sizeof(sampler_state)); 59203b705cfSriastradh sampler_state.ss0.min_filter = BRW_MAPFILTER_LINEAR; 59303b705cfSriastradh sampler_state.ss0.mag_filter = BRW_MAPFILTER_LINEAR; 59403b705cfSriastradh sampler_state.ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 59503b705cfSriastradh sampler_state.ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 59603b705cfSriastradh sampler_state.ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 59703b705cfSriastradh 59813496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 59903b705cfSriastradh &sampler_state, sizeof(sampler_state), 60003b705cfSriastradh "textured video sampler state"); 60103b705cfSriastradh} 60203b705cfSriastradh 60303b705cfSriastradhstatic drm_intel_bo *gen7_create_sampler_state(ScrnInfoPtr scrn) 60403b705cfSriastradh{ 60503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 60603b705cfSriastradh struct gen7_sampler_state sampler_state; 60703b705cfSriastradh 60803b705cfSriastradh memset(&sampler_state, 0, sizeof(sampler_state)); 60903b705cfSriastradh sampler_state.ss0.min_filter = BRW_MAPFILTER_LINEAR; 61003b705cfSriastradh sampler_state.ss0.mag_filter = BRW_MAPFILTER_LINEAR; 61103b705cfSriastradh sampler_state.ss3.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 61203b705cfSriastradh sampler_state.ss3.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 61303b705cfSriastradh sampler_state.ss3.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP; 61403b705cfSriastradh 61513496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 61603b705cfSriastradh &sampler_state, sizeof(sampler_state), 61703b705cfSriastradh "textured video sampler state"); 61803b705cfSriastradh} 61903b705cfSriastradh 62003b705cfSriastradhstatic drm_intel_bo *i965_create_vs_state(ScrnInfoPtr scrn) 62103b705cfSriastradh{ 62203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 62303b705cfSriastradh struct brw_vs_unit_state vs_state; 62403b705cfSriastradh 62503b705cfSriastradh /* Set up the vertex shader to be disabled (passthrough) */ 62603b705cfSriastradh memset(&vs_state, 0, sizeof(vs_state)); 62703b705cfSriastradh if (IS_GEN5(intel)) 62803b705cfSriastradh vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES >> 2; 62903b705cfSriastradh else 63003b705cfSriastradh vs_state.thread4.nr_urb_entries = URB_VS_ENTRIES; 63103b705cfSriastradh vs_state.thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1; 63203b705cfSriastradh vs_state.vs6.vs_enable = 0; 63303b705cfSriastradh vs_state.vs6.vert_cache_disable = 1; 63403b705cfSriastradh 63513496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 63603b705cfSriastradh &vs_state, sizeof(vs_state), 63703b705cfSriastradh "textured video vs state"); 63803b705cfSriastradh} 63903b705cfSriastradh 64003b705cfSriastradhstatic drm_intel_bo *i965_create_program(ScrnInfoPtr scrn, 64103b705cfSriastradh const uint32_t * program, 64203b705cfSriastradh unsigned int program_size) 64303b705cfSriastradh{ 64403b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 64513496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 64603b705cfSriastradh program, program_size, 64703b705cfSriastradh "textured video program"); 64803b705cfSriastradh} 64903b705cfSriastradh 65003b705cfSriastradhstatic drm_intel_bo *i965_create_sf_state(ScrnInfoPtr scrn) 65103b705cfSriastradh{ 65203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 65303b705cfSriastradh drm_intel_bo *sf_bo, *kernel_bo; 65403b705cfSriastradh struct brw_sf_unit_state sf_state; 65503b705cfSriastradh 65603b705cfSriastradh if (IS_GEN5(intel)) 65703b705cfSriastradh kernel_bo = i965_create_program(scrn, 65803b705cfSriastradh &sf_kernel_static_gen5[0][0], 65903b705cfSriastradh sizeof(sf_kernel_static_gen5)); 66003b705cfSriastradh else 66103b705cfSriastradh kernel_bo = i965_create_program(scrn, 66203b705cfSriastradh &sf_kernel_static[0][0], 66303b705cfSriastradh sizeof(sf_kernel_static)); 66403b705cfSriastradh if (!kernel_bo) 66503b705cfSriastradh return NULL; 66603b705cfSriastradh 66703b705cfSriastradh sf_bo = drm_intel_bo_alloc(intel->bufmgr, 66803b705cfSriastradh "textured video sf state", 4096, 66903b705cfSriastradh sizeof(sf_state)); 67003b705cfSriastradh if (sf_bo == NULL) { 67103b705cfSriastradh drm_intel_bo_unreference(kernel_bo); 67203b705cfSriastradh return NULL; 67303b705cfSriastradh } 67403b705cfSriastradh 67503b705cfSriastradh /* Set up the SF kernel to do coord interp: for each attribute, 67603b705cfSriastradh * calculate dA/dx and dA/dy. Hand these interpolation coefficients 67703b705cfSriastradh * back to SF which then hands pixels off to WM. 67803b705cfSriastradh */ 67903b705cfSriastradh memset(&sf_state, 0, sizeof(sf_state)); 68003b705cfSriastradh sf_state.thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF); 68103b705cfSriastradh sf_state.thread0.kernel_start_pointer = 68213496ba1Ssnj intel_uxa_emit_reloc(sf_bo, offsetof(struct brw_sf_unit_state, thread0), 68303b705cfSriastradh kernel_bo, sf_state.thread0.grf_reg_count << 1, 68403b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; 68503b705cfSriastradh sf_state.sf1.single_program_flow = 1; /* XXX */ 68603b705cfSriastradh sf_state.sf1.binding_table_entry_count = 0; 68703b705cfSriastradh sf_state.sf1.thread_priority = 0; 68803b705cfSriastradh sf_state.sf1.floating_point_mode = 0; /* Mesa does this */ 68903b705cfSriastradh sf_state.sf1.illegal_op_exception_enable = 1; 69003b705cfSriastradh sf_state.sf1.mask_stack_exception_enable = 1; 69103b705cfSriastradh sf_state.sf1.sw_exception_enable = 1; 69203b705cfSriastradh sf_state.thread2.per_thread_scratch_space = 0; 69303b705cfSriastradh /* scratch space is not used in our kernel */ 69403b705cfSriastradh sf_state.thread2.scratch_space_base_pointer = 0; 69503b705cfSriastradh sf_state.thread3.const_urb_entry_read_length = 0; /* no const URBs */ 69603b705cfSriastradh sf_state.thread3.const_urb_entry_read_offset = 0; /* no const URBs */ 69703b705cfSriastradh sf_state.thread3.urb_entry_read_length = 1; /* 1 URB per vertex */ 69803b705cfSriastradh sf_state.thread3.urb_entry_read_offset = 0; 69903b705cfSriastradh sf_state.thread3.dispatch_grf_start_reg = 3; 70003b705cfSriastradh sf_state.thread4.max_threads = SF_MAX_THREADS - 1; 70103b705cfSriastradh sf_state.thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1; 70203b705cfSriastradh sf_state.thread4.nr_urb_entries = URB_SF_ENTRIES; 70303b705cfSriastradh sf_state.thread4.stats_enable = 1; 70403b705cfSriastradh sf_state.sf5.viewport_transform = FALSE; /* skip viewport */ 70503b705cfSriastradh sf_state.sf6.cull_mode = BRW_CULLMODE_NONE; 70603b705cfSriastradh sf_state.sf6.scissor = 0; 70703b705cfSriastradh sf_state.sf7.trifan_pv = 2; 70803b705cfSriastradh sf_state.sf6.dest_org_vbias = 0x8; 70903b705cfSriastradh sf_state.sf6.dest_org_hbias = 0x8; 71003b705cfSriastradh 71103b705cfSriastradh dri_bo_subdata(sf_bo, 0, sizeof(sf_state), &sf_state); 71203b705cfSriastradh return sf_bo; 71303b705cfSriastradh} 71403b705cfSriastradh 71503b705cfSriastradhstatic drm_intel_bo *i965_create_wm_state(ScrnInfoPtr scrn, 71603b705cfSriastradh drm_intel_bo * sampler_bo, 71703b705cfSriastradh Bool is_packed) 71803b705cfSriastradh{ 71903b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 72003b705cfSriastradh drm_intel_bo *wm_bo, *kernel_bo; 72103b705cfSriastradh struct brw_wm_unit_state wm_state; 72203b705cfSriastradh 72303b705cfSriastradh if (is_packed) { 72403b705cfSriastradh if (IS_GEN5(intel)) 72503b705cfSriastradh kernel_bo = 72603b705cfSriastradh i965_create_program(scrn, 72703b705cfSriastradh &ps_kernel_packed_static_gen5[0] 72803b705cfSriastradh [0], 72903b705cfSriastradh sizeof 73003b705cfSriastradh (ps_kernel_packed_static_gen5)); 73103b705cfSriastradh else 73203b705cfSriastradh kernel_bo = 73303b705cfSriastradh i965_create_program(scrn, 73403b705cfSriastradh &ps_kernel_packed_static[0][0], 73503b705cfSriastradh sizeof 73603b705cfSriastradh (ps_kernel_packed_static)); 73703b705cfSriastradh } else { 73803b705cfSriastradh if (IS_GEN5(intel)) 73903b705cfSriastradh kernel_bo = 74003b705cfSriastradh i965_create_program(scrn, 74103b705cfSriastradh &ps_kernel_planar_static_gen5[0] 74203b705cfSriastradh [0], 74303b705cfSriastradh sizeof 74403b705cfSriastradh (ps_kernel_planar_static_gen5)); 74503b705cfSriastradh else 74603b705cfSriastradh kernel_bo = 74703b705cfSriastradh i965_create_program(scrn, 74803b705cfSriastradh &ps_kernel_planar_static[0][0], 74903b705cfSriastradh sizeof 75003b705cfSriastradh (ps_kernel_planar_static)); 75103b705cfSriastradh } 75203b705cfSriastradh if (!kernel_bo) 75303b705cfSriastradh return NULL; 75403b705cfSriastradh 75503b705cfSriastradh wm_bo = drm_intel_bo_alloc(intel->bufmgr, 75603b705cfSriastradh "textured video wm state", 75703b705cfSriastradh sizeof(wm_state), 0); 75803b705cfSriastradh if (wm_bo == NULL) { 75903b705cfSriastradh drm_intel_bo_unreference(kernel_bo); 76003b705cfSriastradh return NULL; 76103b705cfSriastradh } 76203b705cfSriastradh 76303b705cfSriastradh memset(&wm_state, 0, sizeof(wm_state)); 76403b705cfSriastradh wm_state.thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF); 76503b705cfSriastradh wm_state.thread0.kernel_start_pointer = 76613496ba1Ssnj intel_uxa_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, thread0), 76703b705cfSriastradh kernel_bo, wm_state.thread0.grf_reg_count << 1, 76803b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0) >> 6; 76903b705cfSriastradh wm_state.thread1.single_program_flow = 1; /* XXX */ 77003b705cfSriastradh if (is_packed) 77103b705cfSriastradh wm_state.thread1.binding_table_entry_count = 2; 77203b705cfSriastradh else 77303b705cfSriastradh wm_state.thread1.binding_table_entry_count = 7; 77403b705cfSriastradh 77503b705cfSriastradh /* binding table entry count is only used for prefetching, and it has to 77603b705cfSriastradh * be set 0 for Ironlake 77703b705cfSriastradh */ 77803b705cfSriastradh if (IS_GEN5(intel)) 77903b705cfSriastradh wm_state.thread1.binding_table_entry_count = 0; 78003b705cfSriastradh 78103b705cfSriastradh /* Though we never use the scratch space in our WM kernel, it has to be 78203b705cfSriastradh * set, and the minimum allocation is 1024 bytes. 78303b705cfSriastradh */ 78403b705cfSriastradh wm_state.thread2.scratch_space_base_pointer = 0; 78503b705cfSriastradh wm_state.thread2.per_thread_scratch_space = 0; /* 1024 bytes */ 78603b705cfSriastradh wm_state.thread3.dispatch_grf_start_reg = 3; /* XXX */ 78703b705cfSriastradh wm_state.thread3.const_urb_entry_read_length = 0; 78803b705cfSriastradh wm_state.thread3.const_urb_entry_read_offset = 0; 78903b705cfSriastradh wm_state.thread3.urb_entry_read_length = 1; /* XXX */ 79003b705cfSriastradh wm_state.thread3.urb_entry_read_offset = 0; /* XXX */ 79103b705cfSriastradh wm_state.wm4.stats_enable = 1; 79203b705cfSriastradh wm_state.wm4.sampler_state_pointer = 79313496ba1Ssnj intel_uxa_emit_reloc(wm_bo, offsetof(struct brw_wm_unit_state, wm4), 79403b705cfSriastradh sampler_bo, 0, 79503b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; 79603b705cfSriastradh if (IS_GEN5(intel)) 79703b705cfSriastradh wm_state.wm4.sampler_count = 0; 79803b705cfSriastradh else 79903b705cfSriastradh wm_state.wm4.sampler_count = 1; /* 1-4 samplers used */ 80003b705cfSriastradh wm_state.wm5.max_threads = PS_MAX_THREADS - 1; 80103b705cfSriastradh wm_state.wm5.thread_dispatch_enable = 1; 80203b705cfSriastradh wm_state.wm5.enable_16_pix = 1; 80303b705cfSriastradh wm_state.wm5.enable_8_pix = 0; 80403b705cfSriastradh wm_state.wm5.early_depth_test = 1; 80503b705cfSriastradh 80603b705cfSriastradh dri_bo_subdata(wm_bo, 0, sizeof(wm_state), &wm_state); 80703b705cfSriastradh drm_intel_bo_unreference(kernel_bo); 80803b705cfSriastradh return wm_bo; 80903b705cfSriastradh} 81003b705cfSriastradh 81103b705cfSriastradhstatic drm_intel_bo *i965_create_cc_vp_state(ScrnInfoPtr scrn) 81203b705cfSriastradh{ 81303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 81403b705cfSriastradh struct brw_cc_viewport cc_viewport; 81503b705cfSriastradh 81603b705cfSriastradh memset(&cc_viewport, 0, sizeof(cc_viewport)); 81703b705cfSriastradh cc_viewport.min_depth = -1.e35; 81803b705cfSriastradh cc_viewport.max_depth = 1.e35; 81903b705cfSriastradh 82013496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 82103b705cfSriastradh &cc_viewport, sizeof(cc_viewport), 82203b705cfSriastradh "textured video cc viewport"); 82303b705cfSriastradh} 82403b705cfSriastradh 82503b705cfSriastradhstatic drm_intel_bo *i965_create_cc_state(ScrnInfoPtr scrn) 82603b705cfSriastradh{ 82703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 82803b705cfSriastradh drm_intel_bo *cc_bo, *cc_vp_bo; 82903b705cfSriastradh struct brw_cc_unit_state cc_state; 83003b705cfSriastradh 83103b705cfSriastradh cc_vp_bo = i965_create_cc_vp_state(scrn); 83203b705cfSriastradh if (!cc_vp_bo) 83303b705cfSriastradh return NULL; 83403b705cfSriastradh 83503b705cfSriastradh cc_bo = drm_intel_bo_alloc(intel->bufmgr, 83603b705cfSriastradh "textured video cc state", 83703b705cfSriastradh sizeof(cc_state), 0); 83803b705cfSriastradh if (cc_bo == NULL){ 83903b705cfSriastradh drm_intel_bo_unreference(cc_vp_bo); 84003b705cfSriastradh return NULL; 84103b705cfSriastradh } 84203b705cfSriastradh 84303b705cfSriastradh /* Color calculator state */ 84403b705cfSriastradh memset(&cc_state, 0, sizeof(cc_state)); 84503b705cfSriastradh cc_state.cc0.stencil_enable = 0; /* disable stencil */ 84603b705cfSriastradh cc_state.cc2.depth_test = 0; /* disable depth test */ 84703b705cfSriastradh cc_state.cc2.logicop_enable = 1; /* enable logic op */ 84803b705cfSriastradh cc_state.cc3.ia_blend_enable = 1; /* blend alpha just like colors */ 84903b705cfSriastradh cc_state.cc3.blend_enable = 0; /* disable color blend */ 85003b705cfSriastradh cc_state.cc3.alpha_test = 0; /* disable alpha test */ 85103b705cfSriastradh cc_state.cc4.cc_viewport_state_offset = 85213496ba1Ssnj intel_uxa_emit_reloc(cc_bo, offsetof(struct brw_cc_unit_state, cc4), 85303b705cfSriastradh cc_vp_bo, 0, I915_GEM_DOMAIN_INSTRUCTION, 0) >> 5; 85403b705cfSriastradh cc_state.cc5.dither_enable = 0; /* disable dither */ 85503b705cfSriastradh cc_state.cc5.logicop_func = 0xc; /* WHITE */ 85603b705cfSriastradh cc_state.cc5.statistics_enable = 1; 85703b705cfSriastradh cc_state.cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD; 85803b705cfSriastradh cc_state.cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE; 85903b705cfSriastradh cc_state.cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE; 86003b705cfSriastradh 86103b705cfSriastradh dri_bo_subdata(cc_bo, 0, sizeof(cc_state), &cc_state); 86203b705cfSriastradh drm_intel_bo_unreference(cc_vp_bo); 86303b705cfSriastradh 86403b705cfSriastradh return cc_bo; 86503b705cfSriastradh} 86603b705cfSriastradh 86703b705cfSriastradhstatic void 86803b705cfSriastradhi965_emit_video_setup(ScrnInfoPtr scrn, drm_intel_bo * surface_state_binding_table_bo, int n_src_surf, PixmapPtr pixmap) 86903b705cfSriastradh{ 87003b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 87103b705cfSriastradh int urb_vs_start, urb_vs_size; 87203b705cfSriastradh int urb_gs_start, urb_gs_size; 87303b705cfSriastradh int urb_clip_start, urb_clip_size; 87403b705cfSriastradh int urb_sf_start, urb_sf_size; 87503b705cfSriastradh int urb_cs_start, urb_cs_size; 87603b705cfSriastradh int pipe_ctl; 87703b705cfSriastradh 87803b705cfSriastradh IntelEmitInvarientState(scrn); 87903b705cfSriastradh intel->last_3d = LAST_3D_VIDEO; 88003b705cfSriastradh intel->needs_3d_invariant = TRUE; 88103b705cfSriastradh 88203b705cfSriastradh urb_vs_start = 0; 88303b705cfSriastradh urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE; 88403b705cfSriastradh urb_gs_start = urb_vs_start + urb_vs_size; 88503b705cfSriastradh urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE; 88603b705cfSriastradh urb_clip_start = urb_gs_start + urb_gs_size; 88703b705cfSriastradh urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE; 88803b705cfSriastradh urb_sf_start = urb_clip_start + urb_clip_size; 88903b705cfSriastradh urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE; 89003b705cfSriastradh urb_cs_start = urb_sf_start + urb_sf_size; 89103b705cfSriastradh urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE; 89203b705cfSriastradh 89303b705cfSriastradh OUT_BATCH(MI_FLUSH | 89403b705cfSriastradh MI_STATE_INSTRUCTION_CACHE_FLUSH | 89503b705cfSriastradh BRW_MI_GLOBAL_SNAPSHOT_RESET); 89603b705cfSriastradh OUT_BATCH(MI_NOOP); 89703b705cfSriastradh 89803b705cfSriastradh /* brw_debug (scrn, "before base address modify"); */ 89903b705cfSriastradh /* Match Mesa driver setup */ 90003b705cfSriastradh if (INTEL_INFO(intel)->gen >= 045) 90103b705cfSriastradh OUT_BATCH(NEW_PIPELINE_SELECT | PIPELINE_SELECT_3D); 90203b705cfSriastradh else 90303b705cfSriastradh OUT_BATCH(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D); 90403b705cfSriastradh 90503b705cfSriastradh /* Mesa does this. Who knows... */ 90603b705cfSriastradh OUT_BATCH(BRW_CS_URB_STATE | 0); 90703b705cfSriastradh OUT_BATCH((0 << 4) | /* URB Entry Allocation Size */ 90803b705cfSriastradh (0 << 0)); /* Number of URB Entries */ 90903b705cfSriastradh 91003b705cfSriastradh /* Zero out the two base address registers so all offsets are 91103b705cfSriastradh * absolute 91203b705cfSriastradh */ 91303b705cfSriastradh if (IS_GEN5(intel)) { 91403b705cfSriastradh OUT_BATCH(BRW_STATE_BASE_ADDRESS | 6); 91503b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ 91603b705cfSriastradh OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ 91703b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ 91803b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Instruction base address */ 91903b705cfSriastradh /* general state max addr, disabled */ 92003b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 92103b705cfSriastradh /* media object state max addr, disabled */ 92203b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 92303b705cfSriastradh /* Instruction max addr, disabled */ 92403b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 92503b705cfSriastradh } else { 92603b705cfSriastradh OUT_BATCH(BRW_STATE_BASE_ADDRESS | 4); 92703b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */ 92803b705cfSriastradh OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ 92903b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */ 93003b705cfSriastradh /* general state max addr, disabled */ 93103b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 93203b705cfSriastradh /* media object state max addr, disabled */ 93303b705cfSriastradh OUT_BATCH(0 | BASE_ADDRESS_MODIFY); 93403b705cfSriastradh } 93503b705cfSriastradh 93603b705cfSriastradh /* Set system instruction pointer */ 93703b705cfSriastradh OUT_BATCH(BRW_STATE_SIP | 0); 93803b705cfSriastradh /* system instruction pointer */ 93903b705cfSriastradh OUT_RELOC(intel->video.gen4_sip_kernel_bo, 94003b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 94103b705cfSriastradh 94203b705cfSriastradh /* brw_debug (scrn, "after base address modify"); */ 94303b705cfSriastradh 94403b705cfSriastradh if (IS_GEN5(intel)) 94503b705cfSriastradh pipe_ctl = BRW_PIPE_CONTROL_NOWRITE; 94603b705cfSriastradh else 94703b705cfSriastradh pipe_ctl = BRW_PIPE_CONTROL_NOWRITE | BRW_PIPE_CONTROL_IS_FLUSH; 94803b705cfSriastradh 94903b705cfSriastradh /* Pipe control */ 95003b705cfSriastradh OUT_BATCH(BRW_PIPE_CONTROL | pipe_ctl | 2); 95103b705cfSriastradh OUT_BATCH(0); /* Destination address */ 95203b705cfSriastradh OUT_BATCH(0); /* Immediate data low DW */ 95303b705cfSriastradh OUT_BATCH(0); /* Immediate data high DW */ 95403b705cfSriastradh 95503b705cfSriastradh /* Binding table pointers */ 95603b705cfSriastradh OUT_BATCH(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4); 95703b705cfSriastradh OUT_BATCH(0); /* vs */ 95803b705cfSriastradh OUT_BATCH(0); /* gs */ 95903b705cfSriastradh OUT_BATCH(0); /* clip */ 96003b705cfSriastradh OUT_BATCH(0); /* sf */ 96103b705cfSriastradh /* Only the PS uses the binding table */ 96203b705cfSriastradh OUT_BATCH((n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); 96303b705cfSriastradh 96403b705cfSriastradh /* Blend constant color (magenta is fun) */ 96503b705cfSriastradh OUT_BATCH(BRW_3DSTATE_CONSTANT_COLOR | 3); 96603b705cfSriastradh OUT_BATCH(float_to_uint(1.0)); 96703b705cfSriastradh OUT_BATCH(float_to_uint(0.0)); 96803b705cfSriastradh OUT_BATCH(float_to_uint(1.0)); 96903b705cfSriastradh OUT_BATCH(float_to_uint(1.0)); 97003b705cfSriastradh 97103b705cfSriastradh /* The drawing rectangle clipping is always on. Set it to values that 97203b705cfSriastradh * shouldn't do any clipping. 97303b705cfSriastradh */ 97403b705cfSriastradh OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */ 97503b705cfSriastradh OUT_BATCH(0x00000000); /* ymin, xmin */ 97603b705cfSriastradh OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16); /* ymax, xmax */ 97703b705cfSriastradh OUT_BATCH(0x00000000); /* yorigin, xorigin */ 97803b705cfSriastradh 97903b705cfSriastradh /* skip the depth buffer */ 98003b705cfSriastradh /* skip the polygon stipple */ 98103b705cfSriastradh /* skip the polygon stipple offset */ 98203b705cfSriastradh /* skip the line stipple */ 98303b705cfSriastradh 98403b705cfSriastradh /* Set the pointers to the 3d pipeline state */ 98503b705cfSriastradh OUT_BATCH(BRW_3DSTATE_PIPELINED_POINTERS | 5); 98603b705cfSriastradh OUT_RELOC(intel->video.gen4_vs_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 98703b705cfSriastradh /* disable GS, resulting in passthrough */ 98803b705cfSriastradh OUT_BATCH(BRW_GS_DISABLE); 98903b705cfSriastradh /* disable CLIP, resulting in passthrough */ 99003b705cfSriastradh OUT_BATCH(BRW_CLIP_DISABLE); 99103b705cfSriastradh OUT_RELOC(intel->video.gen4_sf_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 99203b705cfSriastradh if (n_src_surf == 1) 99303b705cfSriastradh OUT_RELOC(intel->video.gen4_wm_packed_bo, 99403b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 99503b705cfSriastradh else 99603b705cfSriastradh OUT_RELOC(intel->video.gen4_wm_planar_bo, 99703b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 99803b705cfSriastradh OUT_RELOC(intel->video.gen4_cc_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0); 99903b705cfSriastradh 100003b705cfSriastradh /* URB fence */ 100103b705cfSriastradh OUT_BATCH(BRW_URB_FENCE | 100203b705cfSriastradh UF0_CS_REALLOC | 100303b705cfSriastradh UF0_SF_REALLOC | 100403b705cfSriastradh UF0_CLIP_REALLOC | UF0_GS_REALLOC | UF0_VS_REALLOC | 1); 100503b705cfSriastradh OUT_BATCH(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) | 100603b705cfSriastradh ((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) | 100703b705cfSriastradh ((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT)); 100803b705cfSriastradh OUT_BATCH(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) | 100903b705cfSriastradh ((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT)); 101003b705cfSriastradh 101103b705cfSriastradh /* Constant buffer state */ 101203b705cfSriastradh OUT_BATCH(BRW_CS_URB_STATE | 0); 101303b705cfSriastradh OUT_BATCH(((URB_CS_ENTRY_SIZE - 1) << 4) | (URB_CS_ENTRIES << 0)); 101403b705cfSriastradh 101503b705cfSriastradh /* Set up our vertex elements, sourced from the single vertex buffer. */ 101603b705cfSriastradh 101703b705cfSriastradh if (IS_GEN5(intel)) { 101803b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | 3); 101903b705cfSriastradh /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ 102003b705cfSriastradh OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | 102103b705cfSriastradh VE0_VALID | 102203b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 102303b705cfSriastradh (0 << VE0_OFFSET_SHIFT)); 102403b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) 102503b705cfSriastradh | (BRW_VFCOMPONENT_STORE_SRC << 102603b705cfSriastradh VE1_VFCOMPONENT_1_SHIFT) | 102703b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 102803b705cfSriastradh VE1_VFCOMPONENT_2_SHIFT) | 102903b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 103003b705cfSriastradh VE1_VFCOMPONENT_3_SHIFT)); 103103b705cfSriastradh /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ 103203b705cfSriastradh OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | 103303b705cfSriastradh VE0_VALID | 103403b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 103503b705cfSriastradh (8 << VE0_OFFSET_SHIFT)); 103603b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) 103703b705cfSriastradh | (BRW_VFCOMPONENT_STORE_SRC << 103803b705cfSriastradh VE1_VFCOMPONENT_1_SHIFT) | 103903b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 104003b705cfSriastradh VE1_VFCOMPONENT_2_SHIFT) | 104103b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 104203b705cfSriastradh VE1_VFCOMPONENT_3_SHIFT)); 104303b705cfSriastradh } else { 104403b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | 3); 104503b705cfSriastradh /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ 104603b705cfSriastradh OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | 104703b705cfSriastradh VE0_VALID | 104803b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 104903b705cfSriastradh (0 << VE0_OFFSET_SHIFT)); 105003b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) 105103b705cfSriastradh | (BRW_VFCOMPONENT_STORE_SRC << 105203b705cfSriastradh VE1_VFCOMPONENT_1_SHIFT) | 105303b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 105403b705cfSriastradh VE1_VFCOMPONENT_2_SHIFT) | 105503b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 105603b705cfSriastradh VE1_VFCOMPONENT_3_SHIFT) | (0 << 105703b705cfSriastradh VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 105803b705cfSriastradh /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ 105903b705cfSriastradh OUT_BATCH((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) | 106003b705cfSriastradh VE0_VALID | 106103b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 106203b705cfSriastradh (8 << VE0_OFFSET_SHIFT)); 106303b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) 106403b705cfSriastradh | (BRW_VFCOMPONENT_STORE_SRC << 106503b705cfSriastradh VE1_VFCOMPONENT_1_SHIFT) | 106603b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 106703b705cfSriastradh VE1_VFCOMPONENT_2_SHIFT) | 106803b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << 106903b705cfSriastradh VE1_VFCOMPONENT_3_SHIFT) | (4 << 107003b705cfSriastradh VE1_DESTINATION_ELEMENT_OFFSET_SHIFT)); 107103b705cfSriastradh } 107203b705cfSriastradh} 107303b705cfSriastradh 107403b705cfSriastradhvoid 107503b705cfSriastradhI965DisplayVideoTextured(ScrnInfoPtr scrn, 107603b705cfSriastradh intel_adaptor_private *adaptor_priv, int id, 107703b705cfSriastradh RegionPtr dstRegion, 107803b705cfSriastradh short width, short height, 107903b705cfSriastradh int video_pitch, int video_pitch2, 108003b705cfSriastradh short src_w, short src_h, 108103b705cfSriastradh short drw_w, short drw_h, PixmapPtr pixmap) 108203b705cfSriastradh{ 108303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 108403b705cfSriastradh BoxPtr pbox; 108503b705cfSriastradh int nbox, dxo, dyo, pix_xoff, pix_yoff; 108603b705cfSriastradh float src_scale_x, src_scale_y; 108703b705cfSriastradh int src_surf; 108803b705cfSriastradh int n_src_surf; 108903b705cfSriastradh uint32_t src_surf_format; 109003b705cfSriastradh uint32_t src_surf_base[6]; 109103b705cfSriastradh int src_width[6]; 109203b705cfSriastradh int src_height[6]; 109303b705cfSriastradh int src_pitch[6]; 109403b705cfSriastradh drm_intel_bo *surface_state_binding_table_bo; 109503b705cfSriastradh 109603b705cfSriastradh#if 0 109703b705cfSriastradh ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, 109803b705cfSriastradh height, video_pitch); 109903b705cfSriastradh#endif 110003b705cfSriastradh 110103b705cfSriastradh#if 0 110203b705cfSriastradh /* enable debug */ 110303b705cfSriastradh OUTREG(INST_PM, (1 << (16 + 4)) | (1 << 4)); 110403b705cfSriastradh ErrorF("INST_PM 0x%08x\n", INREG(INST_PM)); 110503b705cfSriastradh#endif 110603b705cfSriastradh 110703b705cfSriastradh src_surf_base[0] = adaptor_priv->YBufOffset; 110803b705cfSriastradh src_surf_base[1] = adaptor_priv->YBufOffset; 110903b705cfSriastradh src_surf_base[2] = adaptor_priv->VBufOffset; 111003b705cfSriastradh src_surf_base[3] = adaptor_priv->VBufOffset; 111103b705cfSriastradh src_surf_base[4] = adaptor_priv->UBufOffset; 111203b705cfSriastradh src_surf_base[5] = adaptor_priv->UBufOffset; 111303b705cfSriastradh#if 0 111403b705cfSriastradh ErrorF("base 0 0x%x base 1 0x%x base 2 0x%x\n", 111503b705cfSriastradh src_surf_base[0], src_surf_base[1], src_surf_base[2]); 111603b705cfSriastradh#endif 111703b705cfSriastradh 111803b705cfSriastradh if (is_planar_fourcc(id)) { 111903b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_R8_UNORM; 112003b705cfSriastradh src_width[1] = src_width[0] = width; 112103b705cfSriastradh src_height[1] = src_height[0] = height; 112203b705cfSriastradh src_pitch[1] = src_pitch[0] = video_pitch2; 112303b705cfSriastradh src_width[4] = src_width[5] = src_width[2] = src_width[3] = 112403b705cfSriastradh width / 2; 112503b705cfSriastradh src_height[4] = src_height[5] = src_height[2] = src_height[3] = 112603b705cfSriastradh height / 2; 112703b705cfSriastradh src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = 112803b705cfSriastradh video_pitch; 112903b705cfSriastradh n_src_surf = 6; 113003b705cfSriastradh } else { 113103b705cfSriastradh if (id == FOURCC_UYVY) 113203b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; 113303b705cfSriastradh else 113403b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; 113503b705cfSriastradh 113603b705cfSriastradh src_width[0] = width; 113703b705cfSriastradh src_height[0] = height; 113803b705cfSriastradh src_pitch[0] = video_pitch; 113903b705cfSriastradh n_src_surf = 1; 114003b705cfSriastradh } 114103b705cfSriastradh 114203b705cfSriastradh#if 0 114303b705cfSriastradh ErrorF("dst surf: 0x%08x\n", state_base_offset + dest_surf_offset); 114403b705cfSriastradh ErrorF("src surf: 0x%08x\n", state_base_offset + src_surf_offset); 114503b705cfSriastradh#endif 114603b705cfSriastradh 114703b705cfSriastradh /* We'll be poking the state buffers that could be in use by the 3d 114803b705cfSriastradh * hardware here, but we should have synced the 3D engine already in 114903b705cfSriastradh * I830PutImage. 115003b705cfSriastradh */ 115103b705cfSriastradh 115203b705cfSriastradh surface_state_binding_table_bo = 115303b705cfSriastradh drm_intel_bo_alloc(intel->bufmgr, 115403b705cfSriastradh "surface state & binding table", 115503b705cfSriastradh (n_src_surf + 1) * (SURFACE_STATE_PADDED_SIZE + sizeof(uint32_t)), 115603b705cfSriastradh 4096); 115703b705cfSriastradh 115803b705cfSriastradh if (!surface_state_binding_table_bo) 115903b705cfSriastradh return; 116003b705cfSriastradh 116103b705cfSriastradh i965_create_dst_surface_state(scrn, pixmap, surface_state_binding_table_bo, 0); 116203b705cfSriastradh 116303b705cfSriastradh for (src_surf = 0; src_surf < n_src_surf; src_surf++) { 116403b705cfSriastradh i965_create_src_surface_state(scrn, 116503b705cfSriastradh adaptor_priv->buf, 116603b705cfSriastradh src_surf_base[src_surf], 116703b705cfSriastradh src_width[src_surf], 116803b705cfSriastradh src_height[src_surf], 116903b705cfSriastradh src_pitch[src_surf], 117003b705cfSriastradh src_surf_format, 117103b705cfSriastradh surface_state_binding_table_bo, 117203b705cfSriastradh (src_surf + 1) * SURFACE_STATE_PADDED_SIZE); 117303b705cfSriastradh } 117403b705cfSriastradh 117503b705cfSriastradh i965_create_binding_table(scrn, surface_state_binding_table_bo, n_src_surf + 1); 117603b705cfSriastradh 117703b705cfSriastradh if (intel->video.gen4_sampler_bo == NULL) 117803b705cfSriastradh intel->video.gen4_sampler_bo = i965_create_sampler_state(scrn); 117903b705cfSriastradh if (intel->video.gen4_sip_kernel_bo == NULL) { 118003b705cfSriastradh intel->video.gen4_sip_kernel_bo = 118103b705cfSriastradh i965_create_program(scrn, &sip_kernel_static[0][0], 118203b705cfSriastradh sizeof(sip_kernel_static)); 118303b705cfSriastradh if (!intel->video.gen4_sip_kernel_bo) { 118403b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 118503b705cfSriastradh return; 118603b705cfSriastradh } 118703b705cfSriastradh } 118803b705cfSriastradh 118903b705cfSriastradh if (intel->video.gen4_vs_bo == NULL) { 119003b705cfSriastradh intel->video.gen4_vs_bo = i965_create_vs_state(scrn); 119103b705cfSriastradh if (!intel->video.gen4_vs_bo) { 119203b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 119303b705cfSriastradh return; 119403b705cfSriastradh } 119503b705cfSriastradh } 119603b705cfSriastradh if (intel->video.gen4_sf_bo == NULL) { 119703b705cfSriastradh intel->video.gen4_sf_bo = i965_create_sf_state(scrn); 119803b705cfSriastradh if (!intel->video.gen4_sf_bo) { 119903b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 120003b705cfSriastradh return; 120103b705cfSriastradh } 120203b705cfSriastradh } 120303b705cfSriastradh if (intel->video.gen4_wm_packed_bo == NULL) { 120403b705cfSriastradh intel->video.gen4_wm_packed_bo = 120503b705cfSriastradh i965_create_wm_state(scrn, intel->video.gen4_sampler_bo, 120603b705cfSriastradh TRUE); 120703b705cfSriastradh if (!intel->video.gen4_wm_packed_bo) { 120803b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 120903b705cfSriastradh return; 121003b705cfSriastradh } 121103b705cfSriastradh } 121203b705cfSriastradh 121303b705cfSriastradh if (intel->video.gen4_wm_planar_bo == NULL) { 121403b705cfSriastradh intel->video.gen4_wm_planar_bo = 121503b705cfSriastradh i965_create_wm_state(scrn, intel->video.gen4_sampler_bo, 121603b705cfSriastradh FALSE); 121703b705cfSriastradh if (!intel->video.gen4_wm_planar_bo) { 121803b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 121903b705cfSriastradh return; 122003b705cfSriastradh } 122103b705cfSriastradh } 122203b705cfSriastradh 122303b705cfSriastradh if (intel->video.gen4_cc_bo == NULL) { 122403b705cfSriastradh intel->video.gen4_cc_bo = i965_create_cc_state(scrn); 122503b705cfSriastradh if (!intel->video.gen4_cc_bo) { 122603b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 122703b705cfSriastradh return; 122803b705cfSriastradh } 122903b705cfSriastradh } 123003b705cfSriastradh 123103b705cfSriastradh /* Set up the offset for translating from the given region (in screen 123203b705cfSriastradh * coordinates) to the backing pixmap. 123303b705cfSriastradh */ 123403b705cfSriastradh#ifdef COMPOSITE 123503b705cfSriastradh pix_xoff = -pixmap->screen_x + pixmap->drawable.x; 123603b705cfSriastradh pix_yoff = -pixmap->screen_y + pixmap->drawable.y; 123703b705cfSriastradh#else 123803b705cfSriastradh pix_xoff = 0; 123903b705cfSriastradh pix_yoff = 0; 124003b705cfSriastradh#endif 124103b705cfSriastradh 124203b705cfSriastradh dxo = dstRegion->extents.x1; 124303b705cfSriastradh dyo = dstRegion->extents.y1; 124403b705cfSriastradh 124503b705cfSriastradh /* Use normalized texture coordinates */ 124603b705cfSriastradh src_scale_x = ((float)src_w / width) / (float)drw_w; 124703b705cfSriastradh src_scale_y = ((float)src_h / height) / (float)drw_h; 124803b705cfSriastradh 124903b705cfSriastradh pbox = REGION_RECTS(dstRegion); 125003b705cfSriastradh nbox = REGION_NUM_RECTS(dstRegion); 125103b705cfSriastradh while (nbox--) { 125203b705cfSriastradh int box_x1 = pbox->x1; 125303b705cfSriastradh int box_y1 = pbox->y1; 125403b705cfSriastradh int box_x2 = pbox->x2; 125503b705cfSriastradh int box_y2 = pbox->y2; 125603b705cfSriastradh int i; 125703b705cfSriastradh float vb[12]; 125803b705cfSriastradh drm_intel_bo *bo_table[] = { 125903b705cfSriastradh NULL, /* vb_bo */ 126003b705cfSriastradh intel->batch_bo, 126103b705cfSriastradh surface_state_binding_table_bo, 126203b705cfSriastradh intel->video.gen4_sampler_bo, 126303b705cfSriastradh intel->video.gen4_sip_kernel_bo, 126403b705cfSriastradh intel->video.gen4_vs_bo, 126503b705cfSriastradh intel->video.gen4_sf_bo, 126603b705cfSriastradh intel->video.gen4_wm_packed_bo, 126703b705cfSriastradh intel->video.gen4_wm_planar_bo, 126803b705cfSriastradh intel->video.gen4_cc_bo, 126903b705cfSriastradh }; 127003b705cfSriastradh 127103b705cfSriastradh pbox++; 127203b705cfSriastradh 127303b705cfSriastradh i = 0; 127403b705cfSriastradh vb[i++] = (box_x2 - dxo) * src_scale_x; 127503b705cfSriastradh vb[i++] = (box_y2 - dyo) * src_scale_y; 127603b705cfSriastradh vb[i++] = (float)box_x2 + pix_xoff; 127703b705cfSriastradh vb[i++] = (float)box_y2 + pix_yoff; 127803b705cfSriastradh 127903b705cfSriastradh vb[i++] = (box_x1 - dxo) * src_scale_x; 128003b705cfSriastradh vb[i++] = (box_y2 - dyo) * src_scale_y; 128103b705cfSriastradh vb[i++] = (float)box_x1 + pix_xoff; 128203b705cfSriastradh vb[i++] = (float)box_y2 + pix_yoff; 128303b705cfSriastradh 128403b705cfSriastradh vb[i++] = (box_x1 - dxo) * src_scale_x; 128503b705cfSriastradh vb[i++] = (box_y1 - dyo) * src_scale_y; 128603b705cfSriastradh vb[i++] = (float)box_x1 + pix_xoff; 128703b705cfSriastradh vb[i++] = (float)box_y1 + pix_yoff; 128803b705cfSriastradh 128913496ba1Ssnj bo_table[0] = intel_uxa_bo_alloc_for_data(intel, 129003b705cfSriastradh vb, sizeof(vb), 129103b705cfSriastradh "textured video vbo"); 129203b705cfSriastradh 129303b705cfSriastradh if (IS_GEN4(intel)) 129403b705cfSriastradh i965_pre_draw_debug(scrn); 129503b705cfSriastradh 129603b705cfSriastradh /* If this command won't fit in the current batch, flush. 129703b705cfSriastradh * Assume that it does after being flushed. 129803b705cfSriastradh */ 129903b705cfSriastradh if (drm_intel_bufmgr_check_aperture_space(bo_table, 130003b705cfSriastradh ARRAY_SIZE(bo_table)) 130103b705cfSriastradh < 0) { 130203b705cfSriastradh intel_batch_submit(scrn); 130303b705cfSriastradh } 130403b705cfSriastradh 130503b705cfSriastradh intel_batch_start_atomic(scrn, 150); 130603b705cfSriastradh 130703b705cfSriastradh i965_emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap); 130803b705cfSriastradh 130903b705cfSriastradh /* Set up the pointer to our vertex buffer */ 131003b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | 3); 131103b705cfSriastradh /* four 32-bit floats per vertex */ 131203b705cfSriastradh OUT_BATCH((0 << VB0_BUFFER_INDEX_SHIFT) | 131303b705cfSriastradh VB0_VERTEXDATA | ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); 131403b705cfSriastradh OUT_RELOC(bo_table[0], I915_GEM_DOMAIN_VERTEX, 0, 0); 131503b705cfSriastradh if (IS_GEN5(intel)) 131603b705cfSriastradh OUT_RELOC(bo_table[0], I915_GEM_DOMAIN_VERTEX, 0, 131703b705cfSriastradh i * 4); 131803b705cfSriastradh else 131903b705cfSriastradh OUT_BATCH(3); /* four corners to our rectangle */ 132003b705cfSriastradh OUT_BATCH(0); /* reserved */ 132103b705cfSriastradh 132203b705cfSriastradh OUT_BATCH(BRW_3DPRIMITIVE | BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | (0 << 9) | /* CTG - indirect vertex count */ 132303b705cfSriastradh 4); 132403b705cfSriastradh OUT_BATCH(3); /* vertex count per instance */ 132503b705cfSriastradh OUT_BATCH(0); /* start vertex offset */ 132603b705cfSriastradh OUT_BATCH(1); /* single instance */ 132703b705cfSriastradh OUT_BATCH(0); /* start instance location */ 132803b705cfSriastradh OUT_BATCH(0); /* index buffer offset, ignored */ 132903b705cfSriastradh OUT_BATCH(MI_NOOP); 133003b705cfSriastradh 133103b705cfSriastradh intel_batch_end_atomic(scrn); 133203b705cfSriastradh 133303b705cfSriastradh drm_intel_bo_unreference(bo_table[0]); 133403b705cfSriastradh 133503b705cfSriastradh if (IS_GEN4(intel)) 133603b705cfSriastradh i965_post_draw_debug(scrn); 133703b705cfSriastradh 133803b705cfSriastradh } 133903b705cfSriastradh 134003b705cfSriastradh /* release reference once we're finished */ 134103b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 134203b705cfSriastradh 134313496ba1Ssnj intel_uxa_debug_flush(scrn); 134403b705cfSriastradh} 134503b705cfSriastradh 134603b705cfSriastradhvoid i965_free_video(ScrnInfoPtr scrn) 134703b705cfSriastradh{ 134803b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 134903b705cfSriastradh 135003b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_vs_bo); 135103b705cfSriastradh intel->video.gen4_vs_bo = NULL; 135203b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_sf_bo); 135303b705cfSriastradh intel->video.gen4_sf_bo = NULL; 135403b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_cc_bo); 135503b705cfSriastradh intel->video.gen4_cc_bo = NULL; 135603b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_wm_packed_bo); 135703b705cfSriastradh intel->video.gen4_wm_packed_bo = NULL; 135803b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_wm_planar_bo); 135903b705cfSriastradh intel->video.gen4_wm_planar_bo = NULL; 136003b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_cc_vp_bo); 136103b705cfSriastradh intel->video.gen4_cc_vp_bo = NULL; 136203b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_sampler_bo); 136303b705cfSriastradh intel->video.gen4_sampler_bo = NULL; 136403b705cfSriastradh drm_intel_bo_unreference(intel->video.gen4_sip_kernel_bo); 136503b705cfSriastradh intel->video.gen4_sip_kernel_bo = NULL; 136603b705cfSriastradh drm_intel_bo_unreference(intel->video.wm_prog_packed_bo); 136703b705cfSriastradh intel->video.wm_prog_packed_bo = NULL; 136803b705cfSriastradh drm_intel_bo_unreference(intel->video.wm_prog_planar_bo); 136903b705cfSriastradh intel->video.wm_prog_planar_bo = NULL; 137003b705cfSriastradh drm_intel_bo_unreference(intel->video.gen6_blend_bo); 137103b705cfSriastradh intel->video.gen6_blend_bo = NULL; 137203b705cfSriastradh drm_intel_bo_unreference(intel->video.gen6_depth_stencil_bo); 137303b705cfSriastradh intel->video.gen6_depth_stencil_bo = NULL; 137403b705cfSriastradh} 137503b705cfSriastradh 137603b705cfSriastradh/* for GEN6+ */ 137703b705cfSriastradhstatic drm_intel_bo * 137803b705cfSriastradhgen6_create_cc_state(ScrnInfoPtr scrn) 137903b705cfSriastradh{ 138003b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 138103b705cfSriastradh struct gen6_color_calc_state cc_state; 138203b705cfSriastradh 138303b705cfSriastradh memset(&cc_state, 0, sizeof(cc_state)); 138403b705cfSriastradh cc_state.constant_r = 1.0; 138503b705cfSriastradh cc_state.constant_g = 0.0; 138603b705cfSriastradh cc_state.constant_b = 1.0; 138703b705cfSriastradh cc_state.constant_a = 1.0; 138803b705cfSriastradh 138913496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 139003b705cfSriastradh &cc_state, sizeof(cc_state), 139103b705cfSriastradh "textured video cc state"); 139203b705cfSriastradh} 139303b705cfSriastradh 139403b705cfSriastradhstatic drm_intel_bo * 139503b705cfSriastradhgen6_create_blend_state(ScrnInfoPtr scrn) 139603b705cfSriastradh{ 139703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 139803b705cfSriastradh struct gen6_blend_state blend_state; 139903b705cfSriastradh 140003b705cfSriastradh memset(&blend_state, 0, sizeof(blend_state)); 140103b705cfSriastradh blend_state.blend1.logic_op_enable = 1; 140203b705cfSriastradh blend_state.blend1.logic_op_func = 0xc; 140303b705cfSriastradh blend_state.blend1.pre_blend_clamp_enable = 1; 140403b705cfSriastradh 140513496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 140603b705cfSriastradh &blend_state, sizeof(blend_state), 140703b705cfSriastradh "textured video blend state"); 140803b705cfSriastradh} 140903b705cfSriastradh 141003b705cfSriastradhstatic drm_intel_bo * 141103b705cfSriastradhgen6_create_depth_stencil_state(ScrnInfoPtr scrn) 141203b705cfSriastradh{ 141303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 141403b705cfSriastradh struct gen6_depth_stencil_state depth_stencil_state; 141503b705cfSriastradh 141603b705cfSriastradh memset(&depth_stencil_state, 0, sizeof(depth_stencil_state)); 141713496ba1Ssnj return intel_uxa_bo_alloc_for_data(intel, 141803b705cfSriastradh &depth_stencil_state, 141903b705cfSriastradh sizeof(depth_stencil_state), 142003b705cfSriastradh "textured video blend state"); 142103b705cfSriastradh} 142203b705cfSriastradh 142303b705cfSriastradhstatic Bool 142403b705cfSriastradhgen6_create_vidoe_objects(ScrnInfoPtr scrn) 142503b705cfSriastradh{ 142603b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 142703b705cfSriastradh drm_intel_bo *(*create_sampler_state)(ScrnInfoPtr); 142803b705cfSriastradh const uint32_t *packed_ps_kernel, *planar_ps_kernel; 142903b705cfSriastradh unsigned int packed_ps_size, planar_ps_size; 143003b705cfSriastradh 143103b705cfSriastradh if (INTEL_INFO(intel)->gen >= 070) { 143203b705cfSriastradh create_sampler_state = gen7_create_sampler_state; 143303b705cfSriastradh packed_ps_kernel = &ps_kernel_packed_static_gen7[0][0]; 143403b705cfSriastradh packed_ps_size = sizeof(ps_kernel_packed_static_gen7); 143503b705cfSriastradh planar_ps_kernel = &ps_kernel_planar_static_gen7[0][0]; 143603b705cfSriastradh planar_ps_size = sizeof(ps_kernel_planar_static_gen7); 143703b705cfSriastradh } else { 143803b705cfSriastradh create_sampler_state = i965_create_sampler_state; 143903b705cfSriastradh packed_ps_kernel = &ps_kernel_packed_static_gen6[0][0]; 144003b705cfSriastradh packed_ps_size = sizeof(ps_kernel_packed_static_gen6); 144103b705cfSriastradh planar_ps_kernel = &ps_kernel_planar_static_gen6[0][0]; 144203b705cfSriastradh planar_ps_size = sizeof(ps_kernel_planar_static_gen6); 144303b705cfSriastradh } 144403b705cfSriastradh 144503b705cfSriastradh if (intel->video.gen4_sampler_bo == NULL) 144603b705cfSriastradh intel->video.gen4_sampler_bo = create_sampler_state(scrn); 144703b705cfSriastradh 144803b705cfSriastradh if (intel->video.wm_prog_packed_bo == NULL) 144903b705cfSriastradh intel->video.wm_prog_packed_bo = 145003b705cfSriastradh i965_create_program(scrn, 145103b705cfSriastradh packed_ps_kernel, 145203b705cfSriastradh packed_ps_size); 145303b705cfSriastradh 145403b705cfSriastradh if (intel->video.wm_prog_planar_bo == NULL) 145503b705cfSriastradh intel->video.wm_prog_planar_bo = 145603b705cfSriastradh i965_create_program(scrn, 145703b705cfSriastradh planar_ps_kernel, 145803b705cfSriastradh planar_ps_size); 145903b705cfSriastradh 146003b705cfSriastradh if (intel->video.gen4_cc_vp_bo == NULL) 146103b705cfSriastradh intel->video.gen4_cc_vp_bo = i965_create_cc_vp_state(scrn); 146203b705cfSriastradh 146303b705cfSriastradh if (intel->video.gen4_cc_bo == NULL) 146403b705cfSriastradh intel->video.gen4_cc_bo = gen6_create_cc_state(scrn); 146503b705cfSriastradh 146603b705cfSriastradh if (intel->video.gen6_blend_bo == NULL) 146703b705cfSriastradh intel->video.gen6_blend_bo = gen6_create_blend_state(scrn); 146803b705cfSriastradh 146903b705cfSriastradh if (intel->video.gen6_depth_stencil_bo == NULL) 147003b705cfSriastradh intel->video.gen6_depth_stencil_bo = gen6_create_depth_stencil_state(scrn); 147103b705cfSriastradh 147203b705cfSriastradh 147303b705cfSriastradh return (intel->video.gen4_sampler_bo != NULL && 147403b705cfSriastradh intel->video.wm_prog_packed_bo != NULL && 147503b705cfSriastradh intel->video.wm_prog_planar_bo != NULL && 147603b705cfSriastradh intel->video.gen4_cc_vp_bo != NULL && 147703b705cfSriastradh intel->video.gen4_cc_bo != NULL && 147803b705cfSriastradh intel->video.gen6_blend_bo != NULL && 147903b705cfSriastradh intel->video.gen6_depth_stencil_bo != NULL); 148003b705cfSriastradh} 148103b705cfSriastradh 148203b705cfSriastradhstatic void 148303b705cfSriastradhgen6_upload_state_base_address(ScrnInfoPtr scrn, drm_intel_bo *surface_state_binding_table_bo) 148403b705cfSriastradh{ 148503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 148603b705cfSriastradh 148703b705cfSriastradh OUT_BATCH(BRW_STATE_BASE_ADDRESS | (10 - 2)); 148803b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state base address */ 148903b705cfSriastradh OUT_RELOC(surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */ 149003b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state base address */ 149103b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object base address */ 149203b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction base address */ 149303b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* General state upper bound */ 149403b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Dynamic state upper bound */ 149503b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Indirect object upper bound */ 149603b705cfSriastradh OUT_BATCH(BASE_ADDRESS_MODIFY); /* Instruction access upper bound */ 149703b705cfSriastradh} 149803b705cfSriastradh 149903b705cfSriastradhstatic void 150003b705cfSriastradhgen6_upload_drawing_rectangle(ScrnInfoPtr scrn, PixmapPtr pixmap) 150103b705cfSriastradh{ 150203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 150303b705cfSriastradh 150403b705cfSriastradh OUT_BATCH(BRW_3DSTATE_DRAWING_RECTANGLE | 2); 150503b705cfSriastradh OUT_BATCH(0x00000000); /* ymin, xmin */ 150603b705cfSriastradh OUT_BATCH((pixmap->drawable.width - 1) | (pixmap->drawable.height - 1) << 16); /* ymax, xmax */ 150703b705cfSriastradh OUT_BATCH(0x00000000); /* yorigin, xorigin */ 150803b705cfSriastradh} 150903b705cfSriastradh 151003b705cfSriastradhstatic void 151103b705cfSriastradhgen6_upload_wm_state(ScrnInfoPtr scrn, Bool is_packed) 151203b705cfSriastradh{ 151303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 151403b705cfSriastradh 151503b705cfSriastradh /* disable WM constant buffer */ 151603b705cfSriastradh OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (5 - 2)); 151703b705cfSriastradh OUT_BATCH(0); 151803b705cfSriastradh OUT_BATCH(0); 151903b705cfSriastradh OUT_BATCH(0); 152003b705cfSriastradh OUT_BATCH(0); 152103b705cfSriastradh 152203b705cfSriastradh OUT_BATCH(GEN6_3DSTATE_WM | (9 - 2)); 152303b705cfSriastradh if (is_packed) { 152403b705cfSriastradh OUT_RELOC(intel->video.wm_prog_packed_bo, 152503b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 152603b705cfSriastradh 0); 152703b705cfSriastradh OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) | 152803b705cfSriastradh (2 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT)); 152903b705cfSriastradh } else { 153003b705cfSriastradh OUT_RELOC(intel->video.wm_prog_planar_bo, 153103b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 153203b705cfSriastradh 0); 153303b705cfSriastradh OUT_BATCH((1 << GEN6_3DSTATE_WM_SAMPLER_COUNT_SHITF) | 153403b705cfSriastradh (7 << GEN6_3DSTATE_WM_BINDING_TABLE_ENTRY_COUNT_SHIFT)); 153503b705cfSriastradh } 153603b705cfSriastradh OUT_BATCH(0); 153703b705cfSriastradh OUT_BATCH((6 << GEN6_3DSTATE_WM_DISPATCH_START_GRF_0_SHIFT)); /* DW4 */ 153803b705cfSriastradh OUT_BATCH(((40 - 1) << GEN6_3DSTATE_WM_MAX_THREADS_SHIFT) | 153903b705cfSriastradh GEN6_3DSTATE_WM_DISPATCH_ENABLE | 154003b705cfSriastradh GEN6_3DSTATE_WM_16_DISPATCH_ENABLE); 154103b705cfSriastradh OUT_BATCH((1 << GEN6_3DSTATE_WM_NUM_SF_OUTPUTS_SHIFT) | 154203b705cfSriastradh GEN6_3DSTATE_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); 154303b705cfSriastradh OUT_BATCH(0); 154403b705cfSriastradh OUT_BATCH(0); 154503b705cfSriastradh} 154603b705cfSriastradh 154703b705cfSriastradhstatic void 154803b705cfSriastradhgen6_upload_vertex_element_state(ScrnInfoPtr scrn) 154903b705cfSriastradh{ 155003b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 155103b705cfSriastradh 155203b705cfSriastradh /* Set up our vertex elements, sourced from the single vertex buffer. */ 155303b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_ELEMENTS | (5 - 2)); 155403b705cfSriastradh /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */ 155503b705cfSriastradh OUT_BATCH((0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | 155603b705cfSriastradh GEN6_VE0_VALID | 155703b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 155803b705cfSriastradh (0 << VE0_OFFSET_SHIFT)); 155903b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | 156003b705cfSriastradh (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | 156103b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | 156203b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); 156303b705cfSriastradh /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */ 156403b705cfSriastradh OUT_BATCH((0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) | 156503b705cfSriastradh GEN6_VE0_VALID | 156603b705cfSriastradh (BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) | 156703b705cfSriastradh (8 << VE0_OFFSET_SHIFT)); 156803b705cfSriastradh OUT_BATCH((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) | 156903b705cfSriastradh (BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) | 157003b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) | 157103b705cfSriastradh (BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT)); 157203b705cfSriastradh} 157303b705cfSriastradh 157403b705cfSriastradhstatic void 157503b705cfSriastradhgen6_upload_vertex_buffer(ScrnInfoPtr scrn, drm_intel_bo *vertex_bo, uint32_t end_address_offset) 157603b705cfSriastradh{ 157703b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 157803b705cfSriastradh 157903b705cfSriastradh /* Set up the pointer to our vertex buffer */ 158003b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | (5 - 2)); 158103b705cfSriastradh /* four 32-bit floats per vertex */ 158203b705cfSriastradh OUT_BATCH((0 << GEN6_VB0_BUFFER_INDEX_SHIFT) | 158303b705cfSriastradh GEN6_VB0_VERTEXDATA | 158403b705cfSriastradh ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); 158503b705cfSriastradh OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); 158603b705cfSriastradh OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, end_address_offset); 158703b705cfSriastradh OUT_BATCH(0); /* reserved */ 158803b705cfSriastradh} 158903b705cfSriastradh 159003b705cfSriastradhstatic void 159103b705cfSriastradhgen6_upload_primitive(ScrnInfoPtr scrn) 159203b705cfSriastradh{ 159303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 159403b705cfSriastradh 159503b705cfSriastradh OUT_BATCH(BRW_3DPRIMITIVE | 159603b705cfSriastradh BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL | 159703b705cfSriastradh (_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) | 159803b705cfSriastradh (0 << 9) | /* Internal Vertex Count */ 159903b705cfSriastradh (6 - 2)); 160003b705cfSriastradh OUT_BATCH(3); /* vertex count per instance */ 160103b705cfSriastradh OUT_BATCH(0); /* start vertex offset */ 160203b705cfSriastradh OUT_BATCH(1); /* single instance */ 160303b705cfSriastradh OUT_BATCH(0); /* start instance location */ 160403b705cfSriastradh OUT_BATCH(0); /* index buffer offset, ignored */ 160503b705cfSriastradh} 160603b705cfSriastradh 160703b705cfSriastradhstatic void 160803b705cfSriastradhgen6_emit_video_setup(ScrnInfoPtr scrn, 160903b705cfSriastradh drm_intel_bo *surface_state_binding_table_bo, int n_src_surf, 161003b705cfSriastradh PixmapPtr pixmap, 161103b705cfSriastradh drm_intel_bo *vertex_bo, uint32_t end_address_offset) 161203b705cfSriastradh{ 161303b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 161403b705cfSriastradh 161503b705cfSriastradh assert(n_src_surf == 1 || n_src_surf == 6); 161603b705cfSriastradh IntelEmitInvarientState(scrn); 161703b705cfSriastradh intel->last_3d = LAST_3D_VIDEO; 161803b705cfSriastradh intel->needs_3d_invariant = TRUE; 161903b705cfSriastradh 162003b705cfSriastradh gen6_upload_invariant_states(intel); 162103b705cfSriastradh gen6_upload_state_base_address(scrn, surface_state_binding_table_bo); 162203b705cfSriastradh gen6_upload_viewport_state_pointers(intel, intel->video.gen4_cc_vp_bo); 162303b705cfSriastradh gen6_upload_urb(intel); 162403b705cfSriastradh gen6_upload_cc_state_pointers(intel, intel->video.gen6_blend_bo, intel->video.gen4_cc_bo, intel->video.gen6_depth_stencil_bo, 0); 162503b705cfSriastradh gen6_upload_sampler_state_pointers(intel, intel->video.gen4_sampler_bo); 162603b705cfSriastradh gen6_upload_vs_state(intel); 162703b705cfSriastradh gen6_upload_gs_state(intel); 162803b705cfSriastradh gen6_upload_clip_state(intel); 162903b705cfSriastradh gen6_upload_sf_state(intel, 1, 0); 163003b705cfSriastradh gen6_upload_wm_state(scrn, n_src_surf == 1 ? TRUE : FALSE); 163103b705cfSriastradh gen6_upload_binding_table(intel, (n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); 163203b705cfSriastradh gen6_upload_depth_buffer_state(intel); 163303b705cfSriastradh gen6_upload_drawing_rectangle(scrn, pixmap); 163403b705cfSriastradh gen6_upload_vertex_element_state(scrn); 163503b705cfSriastradh gen6_upload_vertex_buffer(scrn, vertex_bo, end_address_offset); 163603b705cfSriastradh gen6_upload_primitive(scrn); 163703b705cfSriastradh} 163803b705cfSriastradh 163903b705cfSriastradhstatic void 164003b705cfSriastradhgen7_upload_wm_state(ScrnInfoPtr scrn, Bool is_packed) 164103b705cfSriastradh{ 164203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 164303b705cfSriastradh unsigned int max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_IVB; 164403b705cfSriastradh unsigned int num_samples = 0; 164503b705cfSriastradh 164603b705cfSriastradh if (IS_HSW(intel)) { 164703b705cfSriastradh max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_HSW; 164803b705cfSriastradh num_samples = 1 << GEN7_PS_SAMPLE_MASK_SHIFT_HSW; 164903b705cfSriastradh } 165003b705cfSriastradh 165103b705cfSriastradh /* disable WM constant buffer */ 165203b705cfSriastradh OUT_BATCH(GEN6_3DSTATE_CONSTANT_PS | (7 - 2)); 165303b705cfSriastradh OUT_BATCH(0); 165403b705cfSriastradh OUT_BATCH(0); 165503b705cfSriastradh OUT_BATCH(0); 165603b705cfSriastradh OUT_BATCH(0); 165703b705cfSriastradh OUT_BATCH(0); 165803b705cfSriastradh OUT_BATCH(0); 165903b705cfSriastradh 166003b705cfSriastradh OUT_BATCH(GEN6_3DSTATE_WM | (3 - 2)); 166103b705cfSriastradh OUT_BATCH(GEN7_WM_DISPATCH_ENABLE | 166203b705cfSriastradh GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC); 166303b705cfSriastradh OUT_BATCH(0); 166403b705cfSriastradh 166503b705cfSriastradh OUT_BATCH(GEN7_3DSTATE_PS | (8 - 2)); 166603b705cfSriastradh 166703b705cfSriastradh if (is_packed) { 166803b705cfSriastradh OUT_RELOC(intel->video.wm_prog_packed_bo, 166903b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 167003b705cfSriastradh 0); 167103b705cfSriastradh OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) | 167203b705cfSriastradh (2 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); 167303b705cfSriastradh } else { 167403b705cfSriastradh OUT_RELOC(intel->video.wm_prog_planar_bo, 167503b705cfSriastradh I915_GEM_DOMAIN_INSTRUCTION, 0, 167603b705cfSriastradh 0); 167703b705cfSriastradh OUT_BATCH((1 << GEN7_PS_SAMPLER_COUNT_SHIFT) | 167803b705cfSriastradh (7 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT)); 167903b705cfSriastradh } 168003b705cfSriastradh 168103b705cfSriastradh OUT_BATCH(0); /* scratch space base offset */ 168203b705cfSriastradh OUT_BATCH( 168303b705cfSriastradh ((48 - 1) << max_threads_shift) | num_samples | 168403b705cfSriastradh GEN7_PS_ATTRIBUTE_ENABLE | 168503b705cfSriastradh GEN7_PS_16_DISPATCH_ENABLE); 168603b705cfSriastradh OUT_BATCH( 168703b705cfSriastradh (6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_0)); 168803b705cfSriastradh OUT_BATCH(0); /* kernel 1 pointer */ 168903b705cfSriastradh OUT_BATCH(0); /* kernel 2 pointer */ 169003b705cfSriastradh} 169103b705cfSriastradh 169203b705cfSriastradhstatic void 169303b705cfSriastradhgen7_upload_vertex_buffer(ScrnInfoPtr scrn, drm_intel_bo *vertex_bo, uint32_t end_address_offset) 169403b705cfSriastradh{ 169503b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 169603b705cfSriastradh 169703b705cfSriastradh /* Set up the pointer to our vertex buffer */ 169803b705cfSriastradh OUT_BATCH(BRW_3DSTATE_VERTEX_BUFFERS | (5 - 2)); 169903b705cfSriastradh /* four 32-bit floats per vertex */ 170003b705cfSriastradh OUT_BATCH((0 << GEN6_VB0_BUFFER_INDEX_SHIFT) | 170103b705cfSriastradh GEN6_VB0_VERTEXDATA | 170203b705cfSriastradh GEN7_VB0_ADDRESS_MODIFYENABLE | 170303b705cfSriastradh ((4 * 4) << VB0_BUFFER_PITCH_SHIFT)); 170403b705cfSriastradh OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, 0); 170503b705cfSriastradh OUT_RELOC(vertex_bo, I915_GEM_DOMAIN_VERTEX, 0, end_address_offset); 170603b705cfSriastradh OUT_BATCH(0); /* reserved */ 170703b705cfSriastradh} 170803b705cfSriastradh 170903b705cfSriastradhstatic void 171003b705cfSriastradhgen7_upload_primitive(ScrnInfoPtr scrn) 171103b705cfSriastradh{ 171203b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 171303b705cfSriastradh 171403b705cfSriastradh OUT_BATCH(BRW_3DPRIMITIVE | (7 - 2)); 171503b705cfSriastradh OUT_BATCH(_3DPRIM_RECTLIST | 171603b705cfSriastradh GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL); 171703b705cfSriastradh OUT_BATCH(3); /* vertex count per instance */ 171803b705cfSriastradh OUT_BATCH(0); /* start vertex offset */ 171903b705cfSriastradh OUT_BATCH(1); /* single instance */ 172003b705cfSriastradh OUT_BATCH(0); /* start instance location */ 172103b705cfSriastradh OUT_BATCH(0); 172203b705cfSriastradh} 172303b705cfSriastradh 172403b705cfSriastradhstatic void 172503b705cfSriastradhgen7_emit_video_setup(ScrnInfoPtr scrn, 172603b705cfSriastradh drm_intel_bo *surface_state_binding_table_bo, int n_src_surf, 172703b705cfSriastradh PixmapPtr pixmap, 172803b705cfSriastradh drm_intel_bo *vertex_bo, uint32_t end_address_offset) 172903b705cfSriastradh{ 173003b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 173103b705cfSriastradh 173203b705cfSriastradh assert(n_src_surf == 1 || n_src_surf == 6); 173303b705cfSriastradh IntelEmitInvarientState(scrn); 173403b705cfSriastradh intel->last_3d = LAST_3D_VIDEO; 173503b705cfSriastradh intel->needs_3d_invariant = TRUE; 173603b705cfSriastradh 173703b705cfSriastradh gen6_upload_invariant_states(intel); 173803b705cfSriastradh gen6_upload_state_base_address(scrn, surface_state_binding_table_bo); 173903b705cfSriastradh gen7_upload_viewport_state_pointers(intel, intel->video.gen4_cc_vp_bo); 174003b705cfSriastradh gen7_upload_urb(intel); 174103b705cfSriastradh gen7_upload_cc_state_pointers(intel, intel->video.gen6_blend_bo, intel->video.gen4_cc_bo, intel->video.gen6_depth_stencil_bo, 0); 174203b705cfSriastradh gen7_upload_sampler_state_pointers(intel, intel->video.gen4_sampler_bo); 174303b705cfSriastradh gen7_upload_bypass_states(intel); 174403b705cfSriastradh gen6_upload_vs_state(intel); 174503b705cfSriastradh gen6_upload_clip_state(intel); 174603b705cfSriastradh gen7_upload_sf_state(intel, 1, 0); 174703b705cfSriastradh gen7_upload_wm_state(scrn, n_src_surf == 1 ? TRUE : FALSE); 174803b705cfSriastradh gen7_upload_binding_table(intel, (n_src_surf + 1) * SURFACE_STATE_PADDED_SIZE); 174903b705cfSriastradh gen7_upload_depth_buffer_state(intel); 175003b705cfSriastradh gen6_upload_drawing_rectangle(scrn, pixmap); 175103b705cfSriastradh gen6_upload_vertex_element_state(scrn); 175203b705cfSriastradh gen7_upload_vertex_buffer(scrn, vertex_bo, end_address_offset); 175303b705cfSriastradh gen7_upload_primitive(scrn); 175403b705cfSriastradh} 175503b705cfSriastradh 175603b705cfSriastradhvoid Gen6DisplayVideoTextured(ScrnInfoPtr scrn, 175703b705cfSriastradh intel_adaptor_private *adaptor_priv, int id, 175803b705cfSriastradh RegionPtr dstRegion, 175903b705cfSriastradh short width, short height, 176003b705cfSriastradh int video_pitch, int video_pitch2, 176103b705cfSriastradh short src_w, short src_h, 176203b705cfSriastradh short drw_w, short drw_h, PixmapPtr pixmap) 176303b705cfSriastradh{ 176403b705cfSriastradh intel_screen_private *intel = intel_get_screen_private(scrn); 176503b705cfSriastradh BoxPtr pbox; 176603b705cfSriastradh int nbox, dxo, dyo, pix_xoff, pix_yoff; 176703b705cfSriastradh float src_scale_x, src_scale_y; 176803b705cfSriastradh int src_surf; 176903b705cfSriastradh int n_src_surf; 177003b705cfSriastradh uint32_t src_surf_format; 177103b705cfSriastradh uint32_t src_surf_base[6]; 177203b705cfSriastradh int src_width[6]; 177303b705cfSriastradh int src_height[6]; 177403b705cfSriastradh int src_pitch[6]; 177503b705cfSriastradh drm_intel_bo *surface_state_binding_table_bo; 177603b705cfSriastradh void (*create_dst_surface_state)(ScrnInfoPtr, 177703b705cfSriastradh PixmapPtr, 177803b705cfSriastradh drm_intel_bo *, 177903b705cfSriastradh uint32_t); 178003b705cfSriastradh void (*create_src_surface_state)(ScrnInfoPtr, 178103b705cfSriastradh drm_intel_bo *, 178203b705cfSriastradh uint32_t, int, 178303b705cfSriastradh int, int, uint32_t, 178403b705cfSriastradh drm_intel_bo *, uint32_t); 178503b705cfSriastradh void (*emit_video_setup)(ScrnInfoPtr, 178603b705cfSriastradh drm_intel_bo *, int, 178703b705cfSriastradh PixmapPtr, 178803b705cfSriastradh drm_intel_bo *, uint32_t); 178903b705cfSriastradh 179003b705cfSriastradh if (INTEL_INFO(intel)->gen >= 070) { 179103b705cfSriastradh create_dst_surface_state = gen7_create_dst_surface_state; 179203b705cfSriastradh create_src_surface_state = gen7_create_src_surface_state; 179303b705cfSriastradh emit_video_setup = gen7_emit_video_setup; 179403b705cfSriastradh } else { 179503b705cfSriastradh create_dst_surface_state = i965_create_dst_surface_state; 179603b705cfSriastradh create_src_surface_state = i965_create_src_surface_state; 179703b705cfSriastradh emit_video_setup = gen6_emit_video_setup; 179803b705cfSriastradh } 179903b705cfSriastradh 180003b705cfSriastradh src_surf_base[0] = adaptor_priv->YBufOffset; 180103b705cfSriastradh src_surf_base[1] = adaptor_priv->YBufOffset; 180203b705cfSriastradh src_surf_base[2] = adaptor_priv->VBufOffset; 180303b705cfSriastradh src_surf_base[3] = adaptor_priv->VBufOffset; 180403b705cfSriastradh src_surf_base[4] = adaptor_priv->UBufOffset; 180503b705cfSriastradh src_surf_base[5] = adaptor_priv->UBufOffset; 180603b705cfSriastradh 180703b705cfSriastradh if (is_planar_fourcc(id)) { 180803b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_R8_UNORM; 180903b705cfSriastradh src_width[1] = src_width[0] = width; 181003b705cfSriastradh src_height[1] = src_height[0] = height; 181103b705cfSriastradh src_pitch[1] = src_pitch[0] = video_pitch2; 181203b705cfSriastradh src_width[4] = src_width[5] = src_width[2] = src_width[3] = 181303b705cfSriastradh width / 2; 181403b705cfSriastradh src_height[4] = src_height[5] = src_height[2] = src_height[3] = 181503b705cfSriastradh height / 2; 181603b705cfSriastradh src_pitch[4] = src_pitch[5] = src_pitch[2] = src_pitch[3] = 181703b705cfSriastradh video_pitch; 181803b705cfSriastradh n_src_surf = 6; 181903b705cfSriastradh } else { 182003b705cfSriastradh if (id == FOURCC_UYVY) 182103b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_YCRCB_SWAPY; 182203b705cfSriastradh else 182303b705cfSriastradh src_surf_format = BRW_SURFACEFORMAT_YCRCB_NORMAL; 182403b705cfSriastradh 182503b705cfSriastradh src_width[0] = width; 182603b705cfSriastradh src_height[0] = height; 182703b705cfSriastradh src_pitch[0] = video_pitch; 182803b705cfSriastradh n_src_surf = 1; 182903b705cfSriastradh } 183003b705cfSriastradh 183103b705cfSriastradh surface_state_binding_table_bo = 183203b705cfSriastradh drm_intel_bo_alloc(intel->bufmgr, 183303b705cfSriastradh "surface state & binding table", 183403b705cfSriastradh (n_src_surf + 1) * (SURFACE_STATE_PADDED_SIZE + sizeof(uint32_t)), 183503b705cfSriastradh 4096); 183603b705cfSriastradh 183703b705cfSriastradh if (!surface_state_binding_table_bo) 183803b705cfSriastradh return; 183903b705cfSriastradh 184003b705cfSriastradh create_dst_surface_state(scrn, pixmap, surface_state_binding_table_bo, 0); 184103b705cfSriastradh 184203b705cfSriastradh for (src_surf = 0; src_surf < n_src_surf; src_surf++) { 184303b705cfSriastradh create_src_surface_state(scrn, 184403b705cfSriastradh adaptor_priv->buf, 184503b705cfSriastradh src_surf_base[src_surf], 184603b705cfSriastradh src_width[src_surf], 184703b705cfSriastradh src_height[src_surf], 184803b705cfSriastradh src_pitch[src_surf], 184903b705cfSriastradh src_surf_format, 185003b705cfSriastradh surface_state_binding_table_bo, 185103b705cfSriastradh (src_surf + 1) * SURFACE_STATE_PADDED_SIZE); 185203b705cfSriastradh } 185303b705cfSriastradh 185403b705cfSriastradh i965_create_binding_table(scrn, surface_state_binding_table_bo, n_src_surf + 1); 185503b705cfSriastradh 185603b705cfSriastradh if (!gen6_create_vidoe_objects(scrn)) { 185703b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 185803b705cfSriastradh return; 185903b705cfSriastradh } 186003b705cfSriastradh 186103b705cfSriastradh /* Set up the offset for translating from the given region (in screen 186203b705cfSriastradh * coordinates) to the backing pixmap. 186303b705cfSriastradh */ 186403b705cfSriastradh#ifdef COMPOSITE 186503b705cfSriastradh pix_xoff = -pixmap->screen_x + pixmap->drawable.x; 186603b705cfSriastradh pix_yoff = -pixmap->screen_y + pixmap->drawable.y; 186703b705cfSriastradh#else 186803b705cfSriastradh pix_xoff = 0; 186903b705cfSriastradh pix_yoff = 0; 187003b705cfSriastradh#endif 187103b705cfSriastradh 187203b705cfSriastradh dxo = dstRegion->extents.x1; 187303b705cfSriastradh dyo = dstRegion->extents.y1; 187403b705cfSriastradh 187503b705cfSriastradh /* Use normalized texture coordinates */ 187603b705cfSriastradh src_scale_x = ((float)src_w / width) / (float)drw_w; 187703b705cfSriastradh src_scale_y = ((float)src_h / height) / (float)drw_h; 187803b705cfSriastradh 187903b705cfSriastradh pbox = REGION_RECTS(dstRegion); 188003b705cfSriastradh nbox = REGION_NUM_RECTS(dstRegion); 188103b705cfSriastradh while (nbox--) { 188203b705cfSriastradh int box_x1 = pbox->x1; 188303b705cfSriastradh int box_y1 = pbox->y1; 188403b705cfSriastradh int box_x2 = pbox->x2; 188503b705cfSriastradh int box_y2 = pbox->y2; 188603b705cfSriastradh int i; 188703b705cfSriastradh float vb[12]; 188803b705cfSriastradh drm_intel_bo *bo_table[] = { 188903b705cfSriastradh NULL, /* vb_bo */ 189003b705cfSriastradh intel->batch_bo, 189103b705cfSriastradh surface_state_binding_table_bo, 189203b705cfSriastradh intel->video.gen4_sampler_bo, 189303b705cfSriastradh intel->video.wm_prog_packed_bo, 189403b705cfSriastradh intel->video.wm_prog_planar_bo, 189503b705cfSriastradh intel->video.gen4_cc_vp_bo, 189603b705cfSriastradh intel->video.gen4_cc_bo, 189703b705cfSriastradh intel->video.gen6_blend_bo, 189803b705cfSriastradh intel->video.gen6_depth_stencil_bo, 189903b705cfSriastradh }; 190003b705cfSriastradh 190103b705cfSriastradh pbox++; 190203b705cfSriastradh 190303b705cfSriastradh i = 0; 190403b705cfSriastradh vb[i++] = (box_x2 - dxo) * src_scale_x; 190503b705cfSriastradh vb[i++] = (box_y2 - dyo) * src_scale_y; 190603b705cfSriastradh vb[i++] = (float)box_x2 + pix_xoff; 190703b705cfSriastradh vb[i++] = (float)box_y2 + pix_yoff; 190803b705cfSriastradh 190903b705cfSriastradh vb[i++] = (box_x1 - dxo) * src_scale_x; 191003b705cfSriastradh vb[i++] = (box_y2 - dyo) * src_scale_y; 191103b705cfSriastradh vb[i++] = (float)box_x1 + pix_xoff; 191203b705cfSriastradh vb[i++] = (float)box_y2 + pix_yoff; 191303b705cfSriastradh 191403b705cfSriastradh vb[i++] = (box_x1 - dxo) * src_scale_x; 191503b705cfSriastradh vb[i++] = (box_y1 - dyo) * src_scale_y; 191603b705cfSriastradh vb[i++] = (float)box_x1 + pix_xoff; 191703b705cfSriastradh vb[i++] = (float)box_y1 + pix_yoff; 191803b705cfSriastradh 191913496ba1Ssnj bo_table[0] = intel_uxa_bo_alloc_for_data(intel, 192003b705cfSriastradh vb, sizeof(vb), 192103b705cfSriastradh "video vbo"); 192203b705cfSriastradh 192303b705cfSriastradh /* If this command won't fit in the current batch, flush. 192403b705cfSriastradh * Assume that it does after being flushed. 192503b705cfSriastradh */ 192603b705cfSriastradh if (drm_intel_bufmgr_check_aperture_space(bo_table, ARRAY_SIZE(bo_table)) < 0) 192703b705cfSriastradh intel_batch_submit(scrn); 192803b705cfSriastradh 192903b705cfSriastradh intel_batch_start_atomic(scrn, 200); 193003b705cfSriastradh emit_video_setup(scrn, surface_state_binding_table_bo, n_src_surf, pixmap, bo_table[0], i * 4); 193103b705cfSriastradh intel_batch_end_atomic(scrn); 193203b705cfSriastradh 193303b705cfSriastradh drm_intel_bo_unreference(bo_table[0]); 193403b705cfSriastradh } 193503b705cfSriastradh 193603b705cfSriastradh /* release reference once we're finished */ 193703b705cfSriastradh drm_intel_bo_unreference(surface_state_binding_table_bo); 193813496ba1Ssnj intel_uxa_debug_flush(scrn); 193903b705cfSriastradh} 1940