xvmc: init one-time mc context once

Don't setup one-time mc context everytime, as the content is always
unchanged. And several structs got packed layout inside to ease static
state initialization.
This commit is contained in:
Zhenyu Wang 2008-06-25 14:27:16 +08:00
parent 54f3f528e4
commit b4d8ca8b38
3 changed files with 422 additions and 399 deletions

View File

@ -28,6 +28,8 @@
#ifndef _I915_STRUCTS_H
#define _I915_STRUCTS_H
#include <stdint.h>
/* MI_INSTRUCTION */
#define CMD_MI 0x00
@ -532,6 +534,9 @@ struct i915_3dstate_sampler_state
unsigned sampler_masker : 16;
unsigned pad0 : 16;
} dw1;
/* we always use two samplers for mc */
struct texture_sampler sampler0;
struct texture_sampler sampler1;
};
struct arithmetic_inst
@ -641,17 +646,48 @@ union shader_inst
struct declaration_inst d;
};
struct i915_3dstate_pixel_shader_header {
unsigned length : 9;
unsigned pad0 : 6;
unsigned retain : 1;
unsigned opcode : 13;
unsigned type : 3;
};
struct i915_3dstate_pixel_shader_program
{
struct {
unsigned length : 9;
unsigned pad0 : 6;
unsigned retain : 1;
unsigned opcode : 13;
unsigned type : 3;
} dw0;
struct i915_3dstate_pixel_shader_header shader0;
/* mov oC, c0.0000 */
uint32_t inst0[3];
// union shader_inst *insts;
struct i915_3dstate_pixel_shader_header shader1;
/* dcl t0.xy */
/* dcl t1.xy */
/* dcl_2D s0 */
/* texld r0, t0, s0 */
/* mov oC, r0 */
uint32_t inst1[3*5];
struct i915_3dstate_pixel_shader_header shader2;
/* dcl t2.xy */
/* dcl t3.xy */
/* dcl_2D s1 */
/* texld r0, t2, s1 */
/* mov oC, r0 */
uint32_t inst2[3*5];
struct i915_3dstate_pixel_shader_header shader3;
/* dcl t0.xy */
/* dcl t1.xy */
/* dcl t2.xy */
/* dcl t3.xy */
/* dcl_2D s0 */
/* dcl_2D s1 */
/* texld r0, t0, s0 */
/* texld r0, t2, s1 */
/* add r0, r0, r1*/
/* mov oC, r0 */
uint32_t inst3[3*10];
};
#define REG_CR0 0x00000001
@ -707,7 +743,8 @@ struct i915_3dstate_pixel_shader_constants
struct {
unsigned reg_mask;
} dw1;
// struct shader_constant *consts;
/* we only need one constant */
struct shader_constant value;
};
#define BLOCK_SIS 0x01

View File

@ -81,6 +81,372 @@ static int findOverlap(unsigned int width, unsigned int height,
}
#endif
static void i915_inst_arith(unsigned int *inst,
unsigned int op,
unsigned int dest,
unsigned int mask,
unsigned int saturate,
unsigned int src0, unsigned int src1, unsigned int src2)
{
dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
*inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
inst++;
*inst = (A1_SRC0(src0) | A1_SRC1(src1));
inst++;
*inst = (A2_SRC1(src1) | A2_SRC2(src2));
}
static void i915_inst_decl(unsigned int *inst,
unsigned int type,
unsigned int nr,
unsigned int d0_flags)
{
unsigned int reg = UREG(type, nr);
*inst = (D0_DCL | D0_DEST(reg) | d0_flags);
inst++;
*inst = D1_MBZ;
inst++;
*inst = D2_MBZ;
}
static void i915_inst_texld(unsigned int *inst,
unsigned int op,
unsigned int dest,
unsigned int coord,
unsigned int sampler)
{
dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
*inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
inst++;
*inst = T1_ADDRESS_REG(coord);
inst++;
*inst = T2_MBZ;
}
static void i915_emit_batch(void *data, int size, int flag)
{
intelBatchbufferData(data, size, flag);
}
/* one time context initialization buffer */
static uint32_t *one_time_load_state_imm1;
static uint32_t *one_time_load_indirect;
static int one_time_load_state_imm1_size, one_time_load_indirect_size;
static void i915_mc_one_time_context_init(XvMCContext *context)
{
unsigned int dest, src0, src1, src2;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
int i;
struct i915_3dstate_sampler_state *sampler_state;
struct i915_3dstate_pixel_shader_program *pixel_shader_program;
struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
/* sampler static state */
sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
/* pixel shader static state */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
/* pixel shader contant static state */
pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
memset(sampler_state, 0, sizeof(*sampler_state));
sampler_state->dw0.type = CMD_3D;
sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
sampler_state->dw0.length = 6;
sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
sampler_state->sampler0.ts0.reverse_gamma = 0;
sampler_state->sampler0.ts0.planar2packet = 0;
sampler_state->sampler0.ts0.color_conversion = 0;
sampler_state->sampler0.ts0.chromakey_index = 0;
sampler_state->sampler0.ts0.base_level = 0;
sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE; /* NONE */
sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
sampler_state->sampler0.ts0.lod_bias = 0; /* 0.0 */
sampler_state->sampler0.ts0.shadow_enable = 0;
sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2;
sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS;
sampler_state->sampler0.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
sampler_state->sampler0.ts1.kill_pixel = 0;
sampler_state->sampler0.ts1.keyed_texture_filter = 0;
sampler_state->sampler0.ts1.chromakey_enable = 0;
sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler0.ts1.normalized_coor = 0;
sampler_state->sampler0.ts1.map_index = 0;
sampler_state->sampler0.ts1.east_deinterlacer = 0;
sampler_state->sampler0.ts2.default_color = 0;
sampler_state->sampler1.ts0.reverse_gamma = 0;
sampler_state->sampler1.ts0.planar2packet = 0;
sampler_state->sampler1.ts0.color_conversion = 0;
sampler_state->sampler1.ts0.chromakey_index = 0;
sampler_state->sampler1.ts0.base_level = 0;
sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE; /* NONE */
sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
sampler_state->sampler1.ts0.lod_bias = 0; /* 0.0 */
sampler_state->sampler1.ts0.shadow_enable = 0;
sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2;
sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS;
sampler_state->sampler1.ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
sampler_state->sampler1.ts1.kill_pixel = 0;
sampler_state->sampler1.ts1.keyed_texture_filter = 0;
sampler_state->sampler1.ts1.chromakey_enable = 0;
sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP;
sampler_state->sampler1.ts1.normalized_coor = 0;
sampler_state->sampler1.ts1.map_index = 1;
sampler_state->sampler1.ts1.east_deinterlacer = 0;
sampler_state->sampler1.ts2.default_color = 0;
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
pixel_shader_program->shader0.type = CMD_3D;
pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->shader0.retain = 1;
pixel_shader_program->shader0.length = 2; /* 1 inst */
i = 0;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_CONST, 0);
src1 = 0;
src2 = 0;
i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV,
dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2);
pixel_shader_program->shader1.type = CMD_3D;
pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->shader1.retain = 1;
pixel_shader_program->shader1.length = 14; /* 5 inst */
i = 0;
/* dcl t0.xy */
i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
i+=3;
/* dcl t1.xy */
i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl_2D s0 */
i += 3;
i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
pixel_shader_program->shader2.type = CMD_3D;
pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->shader2.retain = 1;
pixel_shader_program->shader2.length = 14; /* 5 inst */
i = 0;
/* dcl t2.xy */
i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
i += 3;
i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s1 */
i += 3;
i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t2, s1 */
i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
/* Shader 3 */
pixel_shader_program->shader3.type = CMD_3D;
pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->shader3.retain = 1;
pixel_shader_program->shader3.length = 29; /* 10 inst */
i = 0;
/* dcl t0.xy */
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
/* dcl t1.xy */
i += 3;
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl t2.xy */
i += 3;
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
i += 3;
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s0 */
i += 3;
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* dcl_2D s1 */
i += 3;
i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
/* texld r1, t2, s1 */
i += 3;
dest = UREG(REG_TYPE_R, 1);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
/* add r0, r0, r1 */
i += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_R, 1);
src2 = 0;
i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL,
0 /* A0_DEST_SATURATE */, src0, src1, src2);
/* mul oC, r0, c0 */
i += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_CONST, 0);
src2 = 0;
i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
pixel_shader_constants->dw0.type = CMD_3D;
pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
pixel_shader_constants->dw0.length = 4;
pixel_shader_constants->dw1.reg_mask = REG_CR0;
pixel_shader_constants->value.x = 0.5;
pixel_shader_constants->value.y = 0.5;
pixel_shader_constants->value.z = 0.5;
pixel_shader_constants->value.w = 0.5;
}
static void i915_mc_one_time_state_init(XvMCContext *context)
{
struct s3_dword *s3 = NULL;
struct s6_dword *s6 = NULL;
dis_state *dis = NULL;
ssb_state *ssb = NULL;
psp_state *psp = NULL;
psc_state *psc = NULL;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
int mem_select = 1;
struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
struct i915_3dstate_load_indirect *load_indirect;
/* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size);
load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1;
load_state_immediate_1->dw0.type = CMD_3D;
load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
load_state_immediate_1->dw0.load_s3 = 1;
load_state_immediate_1->dw0.load_s6 = 1;
load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2;
s3 = (struct s3_dword *)(++load_state_immediate_1);
s3->set0_pcd = 1;
s3->set1_pcd = 1;
s3->set2_pcd = 1;
s3->set3_pcd = 1;
s3->set4_pcd = 1;
s3->set5_pcd = 1;
s3->set6_pcd = 1;
s3->set7_pcd = 1;
s6 = (struct s6_dword *)(++s3);
s6->alpha_test_enable = 0;
s6->alpha_test_function = 0;
s6->alpha_reference_value = 0;
s6->depth_test_enable = 1;
s6->depth_test_function = 0;
s6->color_buffer_blend = 0;
s6->color_blend_function = 0;
s6->src_blend_factor = 1;
s6->dest_blend_factor = 1;
s6->depth_buffer_write = 0;
s6->color_buffer_write = 1;
s6->triangle_pv = 0;
/* 3DSTATE_LOAD_INDIRECT */
one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
one_time_load_indirect = calloc(1, one_time_load_indirect_size);
load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect;
load_indirect->dw0.type = CMD_3D;
load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
pI915XvMC->deviceID == PCI_CHIP_I945_G ||
pI915XvMC->deviceID == PCI_CHIP_I945_GM)
mem_select = 0;
load_indirect->dw0.mem_select = mem_select;
/* Dynamic indirect state buffer */
dis = (dis_state *)(++load_indirect);
dis->dw0.valid = 0;
dis->dw0.reset = 0;
dis->dw0.buffer_address = 0;
/* Sample state buffer */
ssb = (ssb_state *)(++dis);
ssb->dw0.valid = 1;
ssb->dw0.force = 1;
ssb->dw1.length = 7; /* 8 - 1 */
if (mem_select)
ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
else
ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
/* Pixel shader program buffer */
psp = (psp_state *)(++ssb);
psp->dw0.valid = 1;
psp->dw0.force = 1;
psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
if (mem_select)
psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
else
psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
/* Pixel shader constant buffer */
psc = (psc_state *)(++psp);
psc->dw0.valid = 1;
psc->dw0.force = 1;
psc->dw1.length = 5; /* 6 - 1 */
if (mem_select)
psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
else
psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
}
static void i915_mc_one_time_state_emit(void)
{
i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0);
i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
}
static void i915_flush(int map, int render)
{
struct i915_mi_flush mi_flush;
@ -582,392 +948,6 @@ static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *
intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
}
/* for MC context initialization */
static void i915_mc_sampler_state_buffer(XvMCContext *context)
{
struct i915_3dstate_sampler_state *sampler_state;
struct texture_sampler *ts;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
/* 3DSATE_SAMPLER_STATE */
sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
memset(sampler_state, 0, sizeof(*sampler_state));
sampler_state->dw0.type = CMD_3D;
sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
sampler_state->dw0.length = 6;
sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
/* Sampler 0 */
ts = (struct texture_sampler *)(++sampler_state);
memset(ts, 0, sizeof(*ts));
ts->ts0.reverse_gamma = 0;
ts->ts0.planar2packet = 0;
ts->ts0.color_conversion = 0;
ts->ts0.chromakey_index = 0;
ts->ts0.base_level = 0;
ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */
ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
ts->ts0.lod_bias = 0; /* 0.0 */
ts->ts0.shadow_enable = 0;
ts->ts0.max_anisotropy = ANISORATIO_2;
ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
ts->ts1.kill_pixel = 0;
ts->ts1.keyed_texture_filter = 0;
ts->ts1.chromakey_enable = 0;
ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
ts->ts1.normalized_coor = 0;
ts->ts1.map_index = 0;
ts->ts1.east_deinterlacer = 0;
ts->ts2.default_color = 0;
/* Sampler 1 */
++ts;
memset(ts, 0, sizeof(*ts));
ts->ts0.reverse_gamma = 0;
ts->ts0.planar2packet = 0;
ts->ts0.color_conversion = 0;
ts->ts0.chromakey_index = 0;
ts->ts0.base_level = 0;
ts->ts0.mip_filter = MIPFILTER_NONE; /* NONE */
ts->ts0.mag_filter = MAPFILTER_LINEAR; /* LINEAR */
ts->ts0.min_filter = MAPFILTER_LINEAR; /* LINEAR */
ts->ts0.lod_bias = 0; /* 0.0 */
ts->ts0.shadow_enable = 0;
ts->ts0.max_anisotropy = ANISORATIO_2;
ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
ts->ts1.min_lod = 0; /* 0.0 Maximum Mip Level */
ts->ts1.kill_pixel = 0;
ts->ts1.keyed_texture_filter = 0;
ts->ts1.chromakey_enable = 0;
ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
ts->ts1.normalized_coor = 0;
ts->ts1.map_index = 1;
ts->ts1.east_deinterlacer = 0;
ts->ts2.default_color = 0;
}
static void i915_inst_arith(unsigned int *inst,
unsigned int op,
unsigned int dest,
unsigned int mask,
unsigned int saturate,
unsigned int src0, unsigned int src1, unsigned int src2)
{
dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
*inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
inst++;
*inst = (A1_SRC0(src0) | A1_SRC1(src1));
inst++;
*inst = (A2_SRC1(src1) | A2_SRC2(src2));
}
static void i915_inst_decl(unsigned int *inst,
unsigned int type,
unsigned int nr,
unsigned int d0_flags)
{
unsigned int reg = UREG(type, nr);
*inst = (D0_DCL | D0_DEST(reg) | d0_flags);
inst++;
*inst = D1_MBZ;
inst++;
*inst = D2_MBZ;
}
static void i915_inst_texld(unsigned int *inst,
unsigned int op,
unsigned int dest,
unsigned int coord,
unsigned int sampler)
{
dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
*inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
inst++;
*inst = T1_ADDRESS_REG(coord);
inst++;
*inst = T2_MBZ;
}
static void i915_mc_pixel_shader_program_buffer(XvMCContext *context)
{
struct i915_3dstate_pixel_shader_program *pixel_shader_program;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
unsigned int *inst;
unsigned int dest, src0, src1, src2;
/* Shader 0 */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
pixel_shader_program->dw0.type = CMD_3D;
pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->dw0.retain = 1;
pixel_shader_program->dw0.length = 2;
/* mov oC, c0.0000 */
inst = (unsigned int*)(++pixel_shader_program);
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_CONST, 0);
src1 = 0;
src2 = 0;
i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
inst += 3;
/* Shader 1 */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
pixel_shader_program->dw0.type = CMD_3D;
pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->dw0.retain = 1;
pixel_shader_program->dw0.length = 14;
/* dcl t0.xy */
inst = (unsigned int*)(++pixel_shader_program);
i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
/* dcl t1.xy */
inst += 3;
i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl_2D s0 */
inst += 3;
i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
inst += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
inst += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
inst += 3;
/* Shader 2 */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
pixel_shader_program->dw0.type = CMD_3D;
pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->dw0.retain = 1;
pixel_shader_program->dw0.length = 14;
/* dcl t2.xy */
inst = (unsigned int*)(++pixel_shader_program);
i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
inst += 3;
i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s1 */
inst += 3;
i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t2, s1 */
inst += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
/* mov oC, r0 */
inst += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = src2 = 0;
i915_inst_arith(inst, A0_MOV, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
inst += 3;
/* Shader 3 */
pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)inst;
memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
pixel_shader_program->dw0.type = CMD_3D;
pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
pixel_shader_program->dw0.retain = 1;
pixel_shader_program->dw0.length = 29;
/* dcl t0.xy */
inst = (unsigned int*)(++pixel_shader_program);
i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
/* dcl t1.xy */
inst += 3;
i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
/* dcl t2.xy */
inst += 3;
i915_inst_decl(inst, REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
/* dcl t3.xy */
inst += 3;
i915_inst_decl(inst, REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
/* dcl_2D s0 */
inst += 3;
i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
/* dcl_2D s1 */
inst += 3;
i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
/* texld r0, t0, s0 */
inst += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_T, 0); /* COORD */
src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
/* texld r1, t2, s1 */
inst += 3;
dest = UREG(REG_TYPE_R, 1);
src0 = UREG(REG_TYPE_T, 2); /* COORD */
src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
/* add r0, r0, r1 */
inst += 3;
dest = UREG(REG_TYPE_R, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_R, 1);
src2 = 0;
i915_inst_arith(inst, A0_ADD, dest, A0_DEST_CHANNEL_ALL,
0 /* A0_DEST_SATURATE */, src0, src1, src2);
/* mul oC, r0, c0 */
inst += 3;
dest = UREG(REG_TYPE_OC, 0);
src0 = UREG(REG_TYPE_R, 0);
src1 = UREG(REG_TYPE_CONST, 0);
src2 = 0;
i915_inst_arith(inst, A0_MUL, dest, A0_DEST_CHANNEL_ALL,
A0_DEST_SATURATE, src0, src1, src2);
inst += 3;
}
static void i915_mc_pixel_shader_constants_buffer(XvMCContext *context)
{
struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
float *value;
pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
pixel_shader_constants->dw0.type = CMD_3D;
pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
pixel_shader_constants->dw0.length = 4;
pixel_shader_constants->dw1.reg_mask = REG_CR0;
value = (float *)(++pixel_shader_constants);
*(value++) = 0.5;
*(value++) = 0.5;
*(value++) = 0.5;
*(value++) = 0.5;
}
static void i915_mc_one_time_state_initialization(XvMCContext *context)
{
struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
struct s3_dword *s3 = NULL;
struct s6_dword *s6 = NULL;
struct i915_3dstate_load_indirect *load_indirect = NULL;
dis_state *dis = NULL;
ssb_state *ssb = NULL;
psp_state *psp = NULL;
psc_state *psc = NULL;
i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
unsigned int size;
void *base = NULL;
int mem_select = 1;
/* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
base = calloc(1, size);
load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
load_state_immediate_1->dw0.type = CMD_3D;
load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
load_state_immediate_1->dw0.load_s3 = 1;
load_state_immediate_1->dw0.load_s6 = 1;
load_state_immediate_1->dw0.length = (size >> 2) - 2;
s3 = (struct s3_dword *)(++load_state_immediate_1);
s3->set0_pcd = 1;
s3->set1_pcd = 1;
s3->set2_pcd = 1;
s3->set3_pcd = 1;
s3->set4_pcd = 1;
s3->set5_pcd = 1;
s3->set6_pcd = 1;
s3->set7_pcd = 1;
s6 = (struct s6_dword *)(++s3);
s6->alpha_test_enable = 0;
s6->alpha_test_function = 0;
s6->alpha_reference_value = 0;
s6->depth_test_enable = 1;
s6->depth_test_function = 0;
s6->color_buffer_blend = 0;
s6->color_blend_function = 0;
s6->src_blend_factor = 1;
s6->dest_blend_factor = 1;
s6->depth_buffer_write = 0;
s6->color_buffer_write = 1;
s6->triangle_pv = 0;
intelBatchbufferData(base, size, 0);
free(base);
/* 3DSTATE_LOAD_INDIRECT */
size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
base = calloc(1, size);
load_indirect = (struct i915_3dstate_load_indirect *)base;
load_indirect->dw0.type = CMD_3D;
load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
load_indirect->dw0.length = (size >> 2) - 2;
if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
pI915XvMC->deviceID == PCI_CHIP_I945_G ||
pI915XvMC->deviceID == PCI_CHIP_I945_GM)
mem_select = 0;
load_indirect->dw0.mem_select = mem_select;
/* DIS */
dis = (dis_state *)(++load_indirect);
dis->dw0.valid = 0;
dis->dw0.reset = 0;
dis->dw0.buffer_address = 0;
/* SSB */
ssb = (ssb_state *)(++dis);
ssb->dw0.valid = 1;
ssb->dw0.force = 1;
ssb->dw1.length = 7; /* 8 - 1 */
if (mem_select)
ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
else
ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
/* PSP */
psp = (psp_state *)(++ssb);
psp->dw0.valid = 1;
psp->dw0.force = 1;
psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
if (mem_select)
psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
else
psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
/* PSC */
psc = (psc_state *)(++psp);
psc->dw0.valid = 1;
psc->dw0.force = 1;
psc->dw1.length = 5; /* 6 - 1 */
if (mem_select)
psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
else
psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
intelBatchbufferData(base, size, 0);
free(base);
}
#if 0
static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
{
@ -1683,6 +1663,11 @@ static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context
pI915XvMC->last_flip = 0;
pI915XvMC->port = context->port;
pI915XvMC->ref = 1;
/* preinit state buffers */
i915_mc_one_time_context_init(context);
i915_mc_one_time_state_init(context);
return Success;
}
@ -1695,6 +1680,9 @@ static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
/* Pass Control to the X server to destroy the drm_context_t */
i915_release_resource(display,context);
free(one_time_load_state_imm1);
free(one_time_load_indirect);
return Success;
}
@ -1937,10 +1925,7 @@ static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
// i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
// | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
i915_mc_sampler_state_buffer(context);
i915_mc_pixel_shader_program_buffer(context);
i915_mc_pixel_shader_constants_buffer(context);
i915_mc_one_time_state_initialization(context);
i915_mc_one_time_state_emit();
i915_mc_static_indirect_state_buffer(context, target_surface,
picture_structure, flags,

View File

@ -38,6 +38,7 @@
#include <string.h>
#include <assert.h>
#include <signal.h>
#include <stdint.h>
#include <xf86drm.h>
#include "i830_common.h"