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