i965: add support for new chipsets

1. new PCI ids
2. fix some 3D commands on new chipset
3. fix send instruction on new chipset
4. new VUE vertex header
5. ff_sync message (added by Zou Nan Hai <nanhai.zou@intel.com>)
6. the offset in JMPI is in unit of 64bits on new chipset
7. new cube map layout
This commit is contained in:
Xiang, Haihao 2009-07-13 10:48:43 +08:00
parent f030e2ba17
commit 2995bf0d68
33 changed files with 823 additions and 149 deletions

View File

@ -65,21 +65,31 @@ static void compile_clip_prog( struct brw_context *brw,
c.func.single_program_flow = 1;
c.key = *key;
c.need_ff_sync = BRW_IS_IGDNG(brw);
/* Need to locate the two positions present in vertex + header.
* These are currently hardcoded:
*/
c.header_position_offset = ATTR_SIZE;
for (i = 0, delta = REG_SIZE; i < VERT_RESULT_MAX; i++)
if (BRW_IS_IGDNG(brw))
delta = 3 * REG_SIZE;
else
delta = REG_SIZE;
for (i = 0; i < VERT_RESULT_MAX; i++)
if (c.key.attrs & (1<<i)) {
c.offset[i] = delta;
delta += ATTR_SIZE;
}
c.nr_attrs = brw_count_bits(c.key.attrs);
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
if (BRW_IS_IGDNG(brw))
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
else
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
c.nr_bytes = c.nr_regs * REG_SIZE;
c.prog_data.clip_mode = c.key.clip_mode; /* XXX */
@ -148,7 +158,11 @@ static void upload_clip_prog(struct brw_context *brw)
key.do_flat_shading = (ctx->Light.ShadeModel == GL_FLAT);
/* _NEW_TRANSFORM */
key.nr_userclip = brw_count_bits(ctx->Transform.ClipPlanesEnabled);
key.clip_mode = BRW_CLIPMODE_NORMAL;
if (BRW_IS_IGDNG(brw))
key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
else
key.clip_mode = BRW_CLIPMODE_NORMAL;
/* _NEW_POLYGON */
if (key.primitive == GL_TRIANGLES) {

View File

@ -117,6 +117,7 @@ struct brw_clip_compile {
GLuint header_position_offset;
GLuint offset[VERT_ATTRIB_MAX];
GLboolean need_ff_sync;
};
#define ATTR_SIZE (4*4)
@ -171,5 +172,5 @@ struct brw_reg get_tmp( struct brw_clip_compile *c );
void brw_clip_project_position(struct brw_clip_compile *c,
struct brw_reg pos );
void brw_clip_ff_sync(struct brw_clip_compile *c);
#endif

View File

@ -130,7 +130,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
struct brw_instruction *plane_loop;
struct brw_instruction *plane_active;
struct brw_instruction *is_negative;
struct brw_instruction *is_neg2;
struct brw_instruction *is_neg2 = NULL;
struct brw_instruction *not_culled;
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
@ -148,7 +148,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_clip_init_clipmask(c);
/* -ve rhw workaround */
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
brw_imm_ud(1<<20));
@ -185,7 +185,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
* Both can be negative on GM965/G965 due to RHW workaround
* if so, this object should be rejected.
*/
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_LE, c->reg.dp0, brw_imm_f(0.0));
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
{
@ -210,7 +210,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
/* If both are positive, do nothing */
/* Only on GM965/G965 */
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.dp0, brw_imm_f(0.0));
is_neg2 = brw_IF(p, BRW_EXECUTE_1);
}
@ -225,7 +225,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_ENDIF(p, is_neg2);
}
}
@ -246,6 +246,8 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
if (c->need_ff_sync)
brw_clip_ff_sync(c);
not_culled = brw_IF(p, BRW_EXECUTE_1);
{
brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE);

View File

@ -50,5 +50,7 @@ void brw_emit_point_clip( struct brw_clip_compile *c )
/* Send an empty message to kill the thread:
*/
brw_clip_tri_alloc_regs(c, 0);
if (c->need_ff_sync)
brw_clip_ff_sync(c);
brw_clip_kill_thread(c);
}

View File

@ -95,7 +95,14 @@ clip_unit_create_from_key(struct brw_context *brw,
* even number.
*/
assert(key->nr_urb_entries % 2 == 0);
clip.thread4.max_threads = 2 - 1;
/* Although up to 16 concurrent Clip threads are allowed on IGDNG,
* only 2 threads can output VUEs at a time.
*/
if (BRW_IS_IGDNG(brw))
clip.thread4.max_threads = 16 - 1;
else
clip.thread4.max_threads = 2 - 1;
} else {
assert(key->nr_urb_entries >= 5);
clip.thread4.max_threads = 1 - 1;

View File

@ -77,6 +77,10 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
if (c->nr_attrs & 1) {
for (j = 0; j < 3; j++) {
GLuint delta = c->nr_attrs*16 + 32;
if (BRW_IS_IGDNG(c->func.brw))
delta = c->nr_attrs * 16 + 32 * 3;
brw_MOV(&c->func, byte_offset(c->reg.vertex[j], delta), brw_imm_f(0));
}
}
@ -562,7 +566,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
/* if -ve rhw workaround bit is set,
do cliptest */
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ);
brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2),
brw_imm_ud(1<<20));
@ -579,11 +583,14 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
if (c->key.do_flat_shading)
brw_clip_tri_flat_shade(c);
if (c->key.clip_mode == BRW_CLIPMODE_NORMAL)
if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) ||
(c->key.clip_mode == BRW_CLIPMODE_KERNEL_CLIP))
do_clip_tri(c);
else
maybe_do_clip_tri(c);
if (c->need_ff_sync)
brw_clip_ff_sync(c);
brw_clip_tri_emit_polygon(c);
/* Send an empty message to kill the thread:

View File

@ -496,6 +496,8 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
}
brw_ENDIF(p, do_clip);
if (c->need_ff_sync)
brw_clip_ff_sync(c);
emit_unfilled_primitives(c);
brw_clip_kill_thread(c);
}

View File

@ -140,6 +140,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
/* Just copy the vertex header:
*/
/*
* After CLIP stage, only first 256 bits of the VUE are read
* back on IGDNG, so needn't change it
*/
brw_copy_indirect_to_indirect(p, dest_ptr, v0_ptr, 1);
/* Iterate over each attribute (could be done in pairs?)
@ -147,6 +151,9 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
for (i = 0; i < c->nr_attrs; i++) {
GLuint delta = i*16 + 32;
if (BRW_IS_IGDNG(p->brw))
delta = i * 16 + 32 * 3;
if (delta == c->offset[VERT_RESULT_EDGE]) {
if (force_edgeflag)
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(1));
@ -177,6 +184,10 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c,
if (i & 1) {
GLuint delta = i*16 + 32;
if (BRW_IS_IGDNG(p->brw))
delta = i * 16 + 32 * 3;
brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0));
}
@ -343,3 +354,19 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c )
}
}
void brw_clip_ff_sync(struct brw_clip_compile *c)
{
struct brw_compile *p = &c->func;
brw_ff_sync(p,
c->reg.R0,
0,
c->reg.R0,
1,
1, /* used */
1, /* msg length */
1, /* response length */
0, /* eot */
1, /* write compelete */
0, /* urb offset */
BRW_URB_SWIZZLE_NONE);
}

View File

@ -139,6 +139,7 @@
#define BRW_CLIPMODE_CLIP_NON_REJECTED 2
#define BRW_CLIPMODE_REJECT_ALL 3
#define BRW_CLIPMODE_ACCEPT_ALL 4
#define BRW_CLIPMODE_KERNEL_CLIP 5
#define BRW_CLIP_NDCSPACE 0
#define BRW_CLIP_SCREENSPACE 1
@ -670,6 +671,25 @@
#define BRW_SAMPLER_MESSAGE_SIMD8_LD 3
#define BRW_SAMPLER_MESSAGE_SIMD16_LD 3
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG 0
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_IGDNG 0
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG 0
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG 1
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_BIAS_IGDNG 1
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG 1
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_LOD_IGDNG 2
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_LOD_IGDNG 2
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_LOD_IGDNG 2
#define BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG 3
#define BRW_SAMPLER_MESSAGE_SIMD4X2_SAMPLE_COMPARE_IGDNG 3
#define BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG 3
/* for IGDNG only */
#define BRW_SAMPLER_SIMD_MODE_SIMD4X2 0
#define BRW_SAMPLER_SIMD_MODE_SIMD8 1
#define BRW_SAMPLER_SIMD_MODE_SIMD16 2
#define BRW_SAMPLER_SIMD_MODE_SIMD32_64 3
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDLOW 0
#define BRW_DATAPORT_OWORD_BLOCK_1_OWORDHIGH 1
#define BRW_DATAPORT_OWORD_BLOCK_2_OWORDS 2
@ -819,8 +839,11 @@
#include "intel_chipset.h"
#define BRW_IS_G4X(brw) (IS_G4X((brw)->intel.intelScreen->deviceID))
#define CMD_PIPELINE_SELECT(brw) (BRW_IS_G4X(brw) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
#define CMD_VF_STATISTICS(brw) (BRW_IS_G4X(brw) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
#define URB_SIZES(brw) (BRW_IS_G4X(brw) ? 384 : 256) /* 512 bit units */
#define BRW_IS_IGDNG(brw) (IS_IGDNG((brw)->intel.intelScreen->deviceID))
#define BRW_IS_965(brw) (!(BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)))
#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965)
#define CMD_VF_STATISTICS(brw) ((BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965)
#define URB_SIZES(brw) (BRW_IS_IGDNG(brw) ? 1024 : \
(BRW_IS_G4X(brw) ? 384 : 256)) /* 512 bit units */
#endif

View File

@ -512,7 +512,19 @@ static void brw_emit_vertices(struct brw_context *brw)
OUT_RELOC(input->bo,
I915_GEM_DOMAIN_VERTEX, 0,
input->offset);
OUT_BATCH(brw->vb.max_index);
if (BRW_IS_IGDNG(brw)) {
if (input->stride) {
OUT_RELOC(input->bo,
I915_GEM_DOMAIN_VERTEX, 0,
input->offset + input->stride * input->count);
} else {
assert(input->count == 1);
OUT_RELOC(input->bo,
I915_GEM_DOMAIN_VERTEX, 0,
input->offset + input->element_size);
}
} else
OUT_BATCH(brw->vb.max_index);
OUT_BATCH(0); /* Instance data step rate */
}
ADVANCE_BATCH();
@ -542,11 +554,18 @@ static void brw_emit_vertices(struct brw_context *brw)
BRW_VE0_VALID |
(format << BRW_VE0_FORMAT_SHIFT) |
(0 << BRW_VE0_SRC_OFFSET_SHIFT));
OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
(comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
(comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
(comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
if (BRW_IS_IGDNG(brw))
OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
(comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
(comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
(comp3 << BRW_VE1_COMPONENT_3_SHIFT));
else
OUT_BATCH((comp0 << BRW_VE1_COMPONENT_0_SHIFT) |
(comp1 << BRW_VE1_COMPONENT_1_SHIFT) |
(comp2 << BRW_VE1_COMPONENT_2_SHIFT) |
(comp3 << BRW_VE1_COMPONENT_3_SHIFT) |
((i * 4) << BRW_VE1_DST_OFFSET_SHIFT));
}
ADVANCE_BATCH();
}

View File

@ -816,6 +816,19 @@ void brw_urb_WRITE(struct brw_compile *p,
GLuint offset,
GLuint swizzle);
void brw_ff_sync(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
GLboolean allocate,
GLboolean used,
GLuint msg_length,
GLuint response_length,
GLboolean eot,
GLboolean writes_complete,
GLuint offset,
GLuint swizzle);
void brw_fb_WRITE(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_reg_nr,
@ -835,7 +848,9 @@ void brw_SAMPLE(struct brw_compile *p,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
GLboolean eot);
GLboolean eot,
GLuint header_present,
GLuint simd_mode);
void brw_math_16( struct brw_compile *p,
struct brw_reg dest,

View File

@ -241,7 +241,8 @@ void brw_set_src1( struct brw_instruction *insn,
static void brw_set_math_message( struct brw_instruction *insn,
static void brw_set_math_message( struct brw_context *brw,
struct brw_instruction *insn,
GLuint msg_length,
GLuint response_length,
GLuint function,
@ -252,18 +253,35 @@ static void brw_set_math_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
insn->bits3.math.function = function;
insn->bits3.math.int_type = integer_type;
insn->bits3.math.precision = low_precision;
insn->bits3.math.saturate = saturate;
insn->bits3.math.data_type = dataType;
insn->bits3.math.response_length = response_length;
insn->bits3.math.msg_length = msg_length;
insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
insn->bits3.math.end_of_thread = 0;
if (BRW_IS_IGDNG(brw)) {
insn->bits3.math_igdng.function = function;
insn->bits3.math_igdng.int_type = integer_type;
insn->bits3.math_igdng.precision = low_precision;
insn->bits3.math_igdng.saturate = saturate;
insn->bits3.math_igdng.data_type = dataType;
insn->bits3.math_igdng.snapshot = 0;
insn->bits3.math_igdng.header_present = 0;
insn->bits3.math_igdng.response_length = response_length;
insn->bits3.math_igdng.msg_length = msg_length;
insn->bits3.math_igdng.end_of_thread = 0;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_MATH;
insn->bits2.send_igdng.end_of_thread = 0;
} else {
insn->bits3.math.function = function;
insn->bits3.math.int_type = integer_type;
insn->bits3.math.precision = low_precision;
insn->bits3.math.saturate = saturate;
insn->bits3.math.data_type = dataType;
insn->bits3.math.response_length = response_length;
insn->bits3.math.msg_length = msg_length;
insn->bits3.math.msg_target = BRW_MESSAGE_TARGET_MATH;
insn->bits3.math.end_of_thread = 0;
}
}
static void brw_set_urb_message( struct brw_instruction *insn,
static void brw_set_ff_sync_message( struct brw_context *brw,
struct brw_instruction *insn,
GLboolean allocate,
GLboolean used,
GLuint msg_length,
@ -273,21 +291,64 @@ static void brw_set_urb_message( struct brw_instruction *insn,
GLuint offset,
GLuint swizzle_control )
{
brw_set_src1(insn, brw_imm_d(0));
brw_set_src1(insn, brw_imm_d(0));
insn->bits3.urb.opcode = 0; /* ? */
insn->bits3.urb.offset = offset;
insn->bits3.urb.swizzle_control = swizzle_control;
insn->bits3.urb.allocate = allocate;
insn->bits3.urb.used = used; /* ? */
insn->bits3.urb.complete = complete;
insn->bits3.urb.response_length = response_length;
insn->bits3.urb.msg_length = msg_length;
insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
insn->bits3.urb.end_of_thread = end_of_thread;
insn->bits3.urb_igdng.opcode = 1;
insn->bits3.urb_igdng.offset = offset;
insn->bits3.urb_igdng.swizzle_control = swizzle_control;
insn->bits3.urb_igdng.allocate = allocate;
insn->bits3.urb_igdng.used = used;
insn->bits3.urb_igdng.complete = complete;
insn->bits3.urb_igdng.header_present = 1;
insn->bits3.urb_igdng.response_length = response_length;
insn->bits3.urb_igdng.msg_length = msg_length;
insn->bits3.urb_igdng.end_of_thread = end_of_thread;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
insn->bits2.send_igdng.end_of_thread = end_of_thread;
}
static void brw_set_dp_write_message( struct brw_instruction *insn,
static void brw_set_urb_message( struct brw_context *brw,
struct brw_instruction *insn,
GLboolean allocate,
GLboolean used,
GLuint msg_length,
GLuint response_length,
GLboolean end_of_thread,
GLboolean complete,
GLuint offset,
GLuint swizzle_control )
{
brw_set_src1(insn, brw_imm_d(0));
if (BRW_IS_IGDNG(brw)) {
insn->bits3.urb_igdng.opcode = 0; /* ? */
insn->bits3.urb_igdng.offset = offset;
insn->bits3.urb_igdng.swizzle_control = swizzle_control;
insn->bits3.urb_igdng.allocate = allocate;
insn->bits3.urb_igdng.used = used; /* ? */
insn->bits3.urb_igdng.complete = complete;
insn->bits3.urb_igdng.header_present = 1;
insn->bits3.urb_igdng.response_length = response_length;
insn->bits3.urb_igdng.msg_length = msg_length;
insn->bits3.urb_igdng.end_of_thread = end_of_thread;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_URB;
insn->bits2.send_igdng.end_of_thread = end_of_thread;
} else {
insn->bits3.urb.opcode = 0; /* ? */
insn->bits3.urb.offset = offset;
insn->bits3.urb.swizzle_control = swizzle_control;
insn->bits3.urb.allocate = allocate;
insn->bits3.urb.used = used; /* ? */
insn->bits3.urb.complete = complete;
insn->bits3.urb.response_length = response_length;
insn->bits3.urb.msg_length = msg_length;
insn->bits3.urb.msg_target = BRW_MESSAGE_TARGET_URB;
insn->bits3.urb.end_of_thread = end_of_thread;
}
}
static void brw_set_dp_write_message( struct brw_context *brw,
struct brw_instruction *insn,
GLuint binding_table_index,
GLuint msg_control,
GLuint msg_type,
@ -298,18 +359,33 @@ static void brw_set_dp_write_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
insn->bits3.dp_write.binding_table_index = binding_table_index;
insn->bits3.dp_write.msg_control = msg_control;
insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
insn->bits3.dp_write.msg_type = msg_type;
insn->bits3.dp_write.send_commit_msg = 0;
insn->bits3.dp_write.response_length = response_length;
insn->bits3.dp_write.msg_length = msg_length;
insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
insn->bits3.urb.end_of_thread = end_of_thread;
if (BRW_IS_IGDNG(brw)) {
insn->bits3.dp_write_igdng.binding_table_index = binding_table_index;
insn->bits3.dp_write_igdng.msg_control = msg_control;
insn->bits3.dp_write_igdng.pixel_scoreboard_clear = pixel_scoreboard_clear;
insn->bits3.dp_write_igdng.msg_type = msg_type;
insn->bits3.dp_write_igdng.send_commit_msg = 0;
insn->bits3.dp_write_igdng.header_present = 1;
insn->bits3.dp_write_igdng.response_length = response_length;
insn->bits3.dp_write_igdng.msg_length = msg_length;
insn->bits3.dp_write_igdng.end_of_thread = end_of_thread;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
insn->bits2.send_igdng.end_of_thread = end_of_thread;
} else {
insn->bits3.dp_write.binding_table_index = binding_table_index;
insn->bits3.dp_write.msg_control = msg_control;
insn->bits3.dp_write.pixel_scoreboard_clear = pixel_scoreboard_clear;
insn->bits3.dp_write.msg_type = msg_type;
insn->bits3.dp_write.send_commit_msg = 0;
insn->bits3.dp_write.response_length = response_length;
insn->bits3.dp_write.msg_length = msg_length;
insn->bits3.dp_write.msg_target = BRW_MESSAGE_TARGET_DATAPORT_WRITE;
insn->bits3.dp_write.end_of_thread = end_of_thread;
}
}
static void brw_set_dp_read_message( struct brw_instruction *insn,
static void brw_set_dp_read_message( struct brw_context *brw,
struct brw_instruction *insn,
GLuint binding_table_index,
GLuint msg_control,
GLuint msg_type,
@ -320,15 +396,29 @@ static void brw_set_dp_read_message( struct brw_instruction *insn,
{
brw_set_src1(insn, brw_imm_d(0));
insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
insn->bits3.dp_read.msg_control = msg_control; /*8:11*/
insn->bits3.dp_read.msg_type = msg_type; /*12:13*/
insn->bits3.dp_read.target_cache = target_cache; /*14:15*/
insn->bits3.dp_read.response_length = response_length; /*16:19*/
insn->bits3.dp_read.msg_length = msg_length; /*20:23*/
insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/
insn->bits3.dp_read.pad1 = 0; /*28:30*/
insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/
if (BRW_IS_IGDNG(brw)) {
insn->bits3.dp_read_igdng.binding_table_index = binding_table_index;
insn->bits3.dp_read_igdng.msg_control = msg_control;
insn->bits3.dp_read_igdng.msg_type = msg_type;
insn->bits3.dp_read_igdng.target_cache = target_cache;
insn->bits3.dp_read_igdng.header_present = 1;
insn->bits3.dp_read_igdng.response_length = response_length;
insn->bits3.dp_read_igdng.msg_length = msg_length;
insn->bits3.dp_read_igdng.pad1 = 0;
insn->bits3.dp_read_igdng.end_of_thread = end_of_thread;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_DATAPORT_READ;
insn->bits2.send_igdng.end_of_thread = end_of_thread;
} else {
insn->bits3.dp_read.binding_table_index = binding_table_index; /*0:7*/
insn->bits3.dp_read.msg_control = msg_control; /*8:11*/
insn->bits3.dp_read.msg_type = msg_type; /*12:13*/
insn->bits3.dp_read.target_cache = target_cache; /*14:15*/
insn->bits3.dp_read.response_length = response_length; /*16:19*/
insn->bits3.dp_read.msg_length = msg_length; /*20:23*/
insn->bits3.dp_read.msg_target = BRW_MESSAGE_TARGET_DATAPORT_READ; /*24:27*/
insn->bits3.dp_read.pad1 = 0; /*28:30*/
insn->bits3.dp_read.end_of_thread = end_of_thread; /*31*/
}
}
static void brw_set_sampler_message(struct brw_context *brw,
@ -338,11 +428,25 @@ static void brw_set_sampler_message(struct brw_context *brw,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
GLboolean eot)
GLboolean eot,
GLuint header_present,
GLuint simd_mode)
{
assert(eot == 0);
brw_set_src1(insn, brw_imm_d(0));
if (BRW_IS_G4X(brw)) {
if (BRW_IS_IGDNG(brw)) {
insn->bits3.sampler_igdng.binding_table_index = binding_table_index;
insn->bits3.sampler_igdng.sampler = sampler;
insn->bits3.sampler_igdng.msg_type = msg_type;
insn->bits3.sampler_igdng.simd_mode = simd_mode;
insn->bits3.sampler_igdng.header_present = header_present;
insn->bits3.sampler_igdng.response_length = response_length;
insn->bits3.sampler_igdng.msg_length = msg_length;
insn->bits3.sampler_igdng.end_of_thread = eot;
insn->bits2.send_igdng.sfid = BRW_MESSAGE_TARGET_SAMPLER;
insn->bits2.send_igdng.end_of_thread = eot;
} else if (BRW_IS_G4X(brw)) {
insn->bits3.sampler_g4x.binding_table_index = binding_table_index;
insn->bits3.sampler_g4x.sampler = sampler;
insn->bits3.sampler_g4x.msg_type = msg_type;
@ -729,11 +833,15 @@ void brw_land_fwd_jump(struct brw_compile *p,
struct brw_instruction *jmp_insn)
{
struct brw_instruction *landing = &p->store[p->nr_insn];
GLuint jmpi = 1;
if (BRW_IS_IGDNG(p->brw))
jmpi = 2;
assert(jmp_insn->header.opcode == BRW_OPCODE_JMPI);
assert(jmp_insn->bits1.da1.src1_reg_file = BRW_IMMEDIATE_VALUE);
jmp_insn->bits3.ud = (landing - jmp_insn) - 1;
jmp_insn->bits3.ud = jmpi * ((landing - jmp_insn) - 1);
}
@ -798,7 +906,8 @@ void brw_math( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
brw_set_math_message(insn,
brw_set_math_message(p->brw,
insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@ -834,7 +943,8 @@ void brw_math_16( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
brw_set_math_message(insn,
brw_set_math_message(p->brw,
insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@ -850,7 +960,8 @@ void brw_math_16( struct brw_compile *p,
brw_set_dest(insn, offset(dest,1));
brw_set_src0(insn, src);
brw_set_math_message(insn,
brw_set_math_message(p->brw,
insn,
msg_length, response_length,
function,
BRW_MATH_INTEGER_UNSIGNED,
@ -897,7 +1008,8 @@ void brw_dp_WRITE_16( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
brw_set_dp_write_message(insn,
brw_set_dp_write_message(p->brw,
insn,
255, /* binding table index (255=stateless) */
BRW_DATAPORT_OWORD_BLOCK_4_OWORDS, /* msg_control */
BRW_DATAPORT_WRITE_MESSAGE_OWORD_BLOCK_WRITE, /* msg_type */
@ -942,7 +1054,8 @@ void brw_dp_READ_16( struct brw_compile *p,
brw_set_dest(insn, dest); /* UW? */
brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
brw_set_dp_read_message(insn,
brw_set_dp_read_message(p->brw,
insn,
255, /* binding table index (255=stateless) */
3, /* msg_control (3 means 4 Owords) */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@ -999,7 +1112,8 @@ void brw_dp_READ_4( struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, brw_null_reg());
brw_set_dp_read_message(insn,
brw_set_dp_read_message(p->brw,
insn,
bind_table_index,
0, /* msg_control (0 means 1 Oword) */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@ -1070,7 +1184,8 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, brw_null_reg());
brw_set_dp_read_message(insn,
brw_set_dp_read_message(p->brw,
insn,
bind_table_index,
oword, /* 0 = lower Oword, 1 = upper Oword */
BRW_DATAPORT_READ_MESSAGE_OWORD_BLOCK_READ, /* msg_type */
@ -1100,7 +1215,8 @@ void brw_fb_WRITE(struct brw_compile *p,
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_dp_write_message(insn,
brw_set_dp_write_message(p->brw,
insn,
binding_table_index,
BRW_DATAPORT_RENDER_TARGET_WRITE_SIMD16_SINGLE_SOURCE, /* msg_control */
BRW_DATAPORT_WRITE_MESSAGE_RENDER_TARGET_WRITE, /* msg_type */
@ -1126,7 +1242,9 @@ void brw_SAMPLE(struct brw_compile *p,
GLuint msg_type,
GLuint response_length,
GLuint msg_length,
GLboolean eot)
GLboolean eot,
GLuint header_present,
GLuint simd_mode)
{
GLboolean need_stall = 0;
@ -1201,7 +1319,9 @@ void brw_SAMPLE(struct brw_compile *p,
msg_type,
response_length,
msg_length,
eot);
eot,
header_present,
simd_mode);
}
if (need_stall) {
@ -1244,7 +1364,8 @@ void brw_urb_WRITE(struct brw_compile *p,
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_set_urb_message(insn,
brw_set_urb_message(p->brw,
insn,
allocate,
used,
msg_length,
@ -1255,3 +1376,37 @@ void brw_urb_WRITE(struct brw_compile *p,
swizzle);
}
void brw_ff_sync(struct brw_compile *p,
struct brw_reg dest,
GLuint msg_reg_nr,
struct brw_reg src0,
GLboolean allocate,
GLboolean used,
GLuint msg_length,
GLuint response_length,
GLboolean eot,
GLboolean writes_complete,
GLuint offset,
GLuint swizzle)
{
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
assert(msg_length < 16);
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
insn->header.destreg__conditonalmod = msg_reg_nr;
brw_set_ff_sync_message(p->brw,
insn,
allocate,
used,
msg_length,
response_length,
eot,
writes_complete,
offset,
swizzle);
}

View File

@ -54,12 +54,17 @@ static void compile_gs_prog( struct brw_context *brw,
memset(&c, 0, sizeof(c));
c.key = *key;
c.need_ff_sync = BRW_IS_IGDNG(brw);
/* Need to locate the two positions present in vertex + header.
* These are currently hardcoded:
*/
c.nr_attrs = brw_count_bits(c.key.attrs);
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
if (BRW_IS_IGDNG(brw))
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
else
c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
c.nr_bytes = c.nr_regs * REG_SIZE;

View File

@ -62,6 +62,7 @@ struct brw_gs_compile {
GLuint nr_attrs;
GLuint nr_regs;
GLuint nr_bytes;
GLboolean need_ff_sync;
};
#define ATTR_SIZE (4*4)

View File

@ -101,6 +101,23 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c,
BRW_URB_SWIZZLE_NONE);
}
void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
{
struct brw_compile *p = &c->func;
brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
brw_ff_sync(p,
c->reg.R0,
0,
c->reg.R0,
1,
1, /* used */
1, /* msg length */
1, /* response length */
0, /* eot */
1, /* write compelete */
0, /* urb offset */
BRW_URB_SWIZZLE_NONE);
}
void brw_gs_quads( struct brw_gs_compile *c )
@ -110,6 +127,8 @@ void brw_gs_quads( struct brw_gs_compile *c )
/* Use polygons for correct edgeflag behaviour. Note that vertex 3
* is the PV for quads, but vertex 0 for polygons:
*/
if (c->need_ff_sync)
brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[3], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_POLYGON << 2));
@ -120,6 +139,8 @@ void brw_gs_quad_strip( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 4);
if (c->need_ff_sync)
brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[2], 0, ((_3DPRIM_POLYGON << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[3], 0, (_3DPRIM_POLYGON << 2));
brw_gs_emit_vue(c, c->reg.vertex[0], 0, (_3DPRIM_POLYGON << 2));
@ -129,6 +150,9 @@ void brw_gs_quad_strip( struct brw_gs_compile *c )
void brw_gs_tris( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 3);
if (c->need_ff_sync)
brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_TRILIST << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[1], 0, (_3DPRIM_TRILIST << 2));
brw_gs_emit_vue(c, c->reg.vertex[2], 1, ((_3DPRIM_TRILIST << 2) | R02_PRIM_END));
@ -137,6 +161,9 @@ void brw_gs_tris( struct brw_gs_compile *c )
void brw_gs_lines( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 2);
if (c->need_ff_sync)
brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 0, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_START));
brw_gs_emit_vue(c, c->reg.vertex[1], 1, ((_3DPRIM_LINESTRIP << 2) | R02_PRIM_END));
}
@ -144,6 +171,9 @@ void brw_gs_lines( struct brw_gs_compile *c )
void brw_gs_points( struct brw_gs_compile *c )
{
brw_gs_alloc_regs(c, 1);
if (c->need_ff_sync)
brw_gs_ff_sync(c, 1);
brw_gs_emit_vue(c, c->reg.vertex[0], 1, ((_3DPRIM_POINTLIST << 2) | R02_PRIM_START | R02_PRIM_END));
}

View File

@ -95,6 +95,9 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key)
gs.thread4.max_threads = 0; /* Hardware requirement */
if (BRW_IS_IGDNG(brw))
gs.thread4.rendering_enable = 1;
if (INTEL_DEBUG & DEBUG_STATS)
gs.thread4.stats_enable = 1;

View File

@ -211,7 +211,7 @@ static void emit_depthbuffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
struct intel_region *region = brw->state.depth_region;
unsigned int len = BRW_IS_G4X(brw) ? 6 : 5;
unsigned int len = (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw)) ? 6 : 5;
if (region == NULL) {
BEGIN_BATCH(len, IGNORE_CLIPRECTS);
@ -222,7 +222,7 @@ static void emit_depthbuffer(struct brw_context *brw)
OUT_BATCH(0);
OUT_BATCH(0);
if (BRW_IS_G4X(brw))
if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
OUT_BATCH(0);
ADVANCE_BATCH();
@ -261,7 +261,7 @@ static void emit_depthbuffer(struct brw_context *brw)
((region->height - 1) << 19));
OUT_BATCH(0);
if (BRW_IS_G4X(brw))
if (BRW_IS_G4X(brw) || BRW_IS_IGDNG(brw))
OUT_BATCH(0);
ADVANCE_BATCH();
@ -374,7 +374,7 @@ static void upload_aa_line_parameters(struct brw_context *brw)
{
struct brw_aa_line_parameters balp;
if (!BRW_IS_G4X(brw))
if (BRW_IS_965(brw))
return;
/* use legacy aa line coverage computation */
@ -511,14 +511,27 @@ static void upload_state_base_address( struct brw_context *brw )
/* Output the structure (brw_state_base_address) directly to the
* batchbuffer, so we can emit relocations inline.
*/
BEGIN_BATCH(6, IGNORE_CLIPRECTS);
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
OUT_BATCH(1); /* General state base address */
OUT_BATCH(1); /* Surface state base address */
OUT_BATCH(1); /* Indirect object base address */
OUT_BATCH(1); /* General state upper bound */
OUT_BATCH(1); /* Indirect object upper bound */
ADVANCE_BATCH();
if (BRW_IS_IGDNG(brw)) {
BEGIN_BATCH(8, IGNORE_CLIPRECTS);
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (8 - 2));
OUT_BATCH(1); /* General state base address */
OUT_BATCH(1); /* Surface state base address */
OUT_BATCH(1); /* Indirect object base address */
OUT_BATCH(1); /* Instruction base address */
OUT_BATCH(1); /* General state upper bound */
OUT_BATCH(1); /* Indirect object upper bound */
OUT_BATCH(1); /* Instruction access upper bound */
ADVANCE_BATCH();
} else {
BEGIN_BATCH(6, IGNORE_CLIPRECTS);
OUT_BATCH(CMD_STATE_BASE_ADDRESS << 16 | (6 - 2));
OUT_BATCH(1); /* General state base address */
OUT_BATCH(1); /* Surface state base address */
OUT_BATCH(1); /* Indirect object base address */
OUT_BATCH(1); /* General state upper bound */
OUT_BATCH(1); /* Indirect object upper bound */
ADVANCE_BATCH();
}
}
const struct brw_tracked_state brw_state_base_address = {

View File

@ -151,6 +151,8 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
GLuint jmpi = 1;
if (!nr)
return;
@ -159,18 +161,21 @@ static void do_flatshade_triangle( struct brw_sf_compile *c )
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
if (BRW_IS_IGDNG(p->brw))
jmpi = 2;
brw_push_insn_state(p);
brw_MUL(p, c->pv, c->pv, brw_imm_d(nr*2+1));
brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr*2+1)));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
copy_colors(c, c->vert[2], c->vert[0]);
brw_JMPI(p, ip, ip, brw_imm_d(nr*4+1));
brw_JMPI(p, ip, ip, brw_imm_d(jmpi*(nr*4+1)));
copy_colors(c, c->vert[0], c->vert[1]);
copy_colors(c, c->vert[2], c->vert[1]);
brw_JMPI(p, ip, ip, brw_imm_d(nr*2));
brw_JMPI(p, ip, ip, brw_imm_d(jmpi*nr*2));
copy_colors(c, c->vert[0], c->vert[2]);
copy_colors(c, c->vert[1], c->vert[2]);
@ -184,7 +189,8 @@ static void do_flatshade_line( struct brw_sf_compile *c )
struct brw_compile *p = &c->func;
struct brw_reg ip = brw_ip_reg();
GLuint nr = brw_count_bits(c->key.attrs & VERT_RESULT_COLOR_BITS);
GLuint jmpi = 1;
if (!nr)
return;
@ -193,13 +199,16 @@ static void do_flatshade_line( struct brw_sf_compile *c )
if (c->key.primitive == SF_UNFILLED_TRIS)
return;
if (BRW_IS_IGDNG(p->brw))
jmpi = 2;
brw_push_insn_state(p);
brw_MUL(p, c->pv, c->pv, brw_imm_d(nr+1));
brw_MUL(p, c->pv, c->pv, brw_imm_d(jmpi*(nr+1)));
brw_JMPI(p, ip, ip, c->pv);
copy_colors(c, c->vert[1], c->vert[0]);
brw_JMPI(p, ip, ip, brw_imm_d(nr));
brw_JMPI(p, ip, ip, brw_imm_ud(jmpi*nr));
copy_colors(c, c->vert[0], c->vert[1]);
brw_pop_insn_state(p);

View File

@ -162,7 +162,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
{
struct brw_sf_unit_state sf;
dri_bo *bo;
int chipset_max_threads;
memset(&sf, 0, sizeof(sf));
sf.thread0.grf_reg_count = ALIGN(key->total_grf, 16) / 16 - 1;
@ -171,13 +171,26 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
sf.thread3.dispatch_grf_start_reg = 3;
sf.thread3.urb_entry_read_offset = 1;
if (BRW_IS_IGDNG(brw))
sf.thread3.urb_entry_read_offset = 3;
else
sf.thread3.urb_entry_read_offset = 1;
sf.thread3.urb_entry_read_length = key->urb_entry_read_length;
sf.thread4.nr_urb_entries = key->nr_urb_entries;
sf.thread4.urb_entry_allocation_size = key->sfsize - 1;
/* Each SF thread produces 1 PUE, and there can be up to 24 threads */
sf.thread4.max_threads = MIN2(24, key->nr_urb_entries) - 1;
/* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or
* 48(IGDNG) threads
*/
if (BRW_IS_IGDNG(brw))
chipset_max_threads = 48;
else
chipset_max_threads = 24;
sf.thread4.max_threads = MIN2(chipset_max_threads, key->nr_urb_entries) - 1;
if (INTEL_DEBUG & DEBUG_SINGLE_THREAD)
sf.thread4.max_threads = 0;

View File

@ -823,7 +823,9 @@ struct brw_gs_unit_state
struct
{
GLuint pad0:10;
GLuint pad0:8;
GLuint rendering_enable:1; /* for IGDNG */
GLuint pad4:1;
GLuint stats_enable:1;
GLuint nr_urb_entries:7;
GLuint pad1:1;
@ -931,6 +933,28 @@ struct brw_wm_unit_state
GLfloat global_depth_offset_constant;
GLfloat global_depth_offset_scale;
/* for IGDNG only */
struct {
GLuint pad0:1;
GLuint grf_reg_count_1:3;
GLuint pad1:2;
GLuint kernel_start_pointer_1:26;
} wm8;
struct {
GLuint pad0:1;
GLuint grf_reg_count_2:3;
GLuint pad1:2;
GLuint kernel_start_pointer_2:26;
} wm9;
struct {
GLuint pad0:1;
GLuint grf_reg_count_3:3;
GLuint pad1:2;
GLuint kernel_start_pointer_3:26;
} wm10;
};
struct brw_sampler_default_color {
@ -1306,6 +1330,14 @@ struct brw_instruction
GLuint pad1:6;
} ia16;
struct
{
GLuint pad:26;
GLuint end_of_thread:1;
GLuint pad1:1;
GLuint sfid:4;
} send_igdng; /* for IGDNG only */
} bits2;
union
@ -1392,6 +1424,21 @@ struct brw_instruction
GLuint end_of_thread:1;
} math;
struct {
GLuint function:4;
GLuint int_type:1;
GLuint precision:1;
GLuint saturate:1;
GLuint data_type:1;
GLuint snapshot:1;
GLuint pad0:10;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} math_igdng;
struct {
GLuint binding_table_index:8;
GLuint sampler:4;
@ -1415,8 +1462,37 @@ struct brw_instruction
GLuint end_of_thread:1;
} sampler_g4x;
struct {
GLuint binding_table_index:8;
GLuint sampler:4;
GLuint msg_type:4;
GLuint simd_mode:2;
GLuint pad0:1;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} sampler_igdng;
struct brw_urb_immediate urb;
struct {
GLuint opcode:4;
GLuint offset:6;
GLuint swizzle_control:2;
GLuint pad:1;
GLuint allocate:1;
GLuint used:1;
GLuint complete:1;
GLuint pad0:3;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} urb_igdng;
struct {
GLuint binding_table_index:8;
GLuint msg_control:4;
@ -1429,6 +1505,19 @@ struct brw_instruction
GLuint end_of_thread:1;
} dp_read;
struct {
GLuint binding_table_index:8;
GLuint msg_control:3;
GLuint msg_type:3;
GLuint target_cache:2;
GLuint pad0:3;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} dp_read_igdng;
struct {
GLuint binding_table_index:8;
GLuint msg_control:3;
@ -1442,6 +1531,20 @@ struct brw_instruction
GLuint end_of_thread:1;
} dp_write;
struct {
GLuint binding_table_index:8;
GLuint msg_control:3;
GLuint pixel_scoreboard_clear:1;
GLuint msg_type:3;
GLuint send_commit_msg:1;
GLuint pad0:3;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} dp_write_igdng;
struct {
GLuint pad:16;
GLuint response_length:4;
@ -1451,6 +1554,15 @@ struct brw_instruction
GLuint end_of_thread:1;
} generic;
struct {
GLuint pad:19;
GLuint header_present:1;
GLuint response_length:5;
GLuint msg_length:4;
GLuint pad1:2;
GLuint end_of_thread:1;
} generic_igdng;
GLint d;
GLuint ud;
} bits3;

View File

@ -36,6 +36,7 @@
#include "intel_tex_layout.h"
#include "intel_context.h"
#include "main/macros.h"
#include "intel_chipset.h"
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
@ -48,6 +49,77 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
switch (mt->target) {
case GL_TEXTURE_CUBE_MAP:
if (IS_IGDNG(intel->intelScreen->deviceID)) {
GLuint align_h = 2, align_w = 4;
GLuint level;
GLuint x = 0;
GLuint y = 0;
GLuint width = mt->width0;
GLuint height = mt->height0;
GLuint qpitch = 0;
GLuint y_pitch = 0;
mt->pitch = mt->width0;
intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
y_pitch = ALIGN(height, align_h);
if (mt->compressed) {
mt->pitch = ALIGN(mt->width0, align_w);
qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp;
mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
} else {
qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp;
mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
}
if (mt->first_level != mt->last_level) {
GLuint mip1_width;
if (mt->compressed) {
mip1_width = ALIGN(minify(mt->width0), align_w)
+ ALIGN(minify(minify(mt->width0)), align_w);
} else {
mip1_width = ALIGN(minify(mt->width0), align_w)
+ minify(minify(mt->width0));
}
if (mip1_width > mt->pitch) {
mt->pitch = mip1_width;
}
}
mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch);
for (level = mt->first_level; level <= mt->last_level; level++) {
GLuint img_height;
GLuint nr_images = 6;
GLuint q = 0;
intel_miptree_set_level_info(mt, level, nr_images, x, y, width,
height, 1);
for (q = 0; q < nr_images; q++)
intel_miptree_set_image_offset_ex(mt, level, q, x, y, q * qpitch);
if (mt->compressed)
img_height = MAX2(1, height/4);
else
img_height = ALIGN(height, align_h);
if (level == mt->first_level + 1) {
x += ALIGN(width, align_w);
}
else {
y += img_height;
}
width = minify(width);
height = minify(height);
}
break;
}
case GL_TEXTURE_3D: {
GLuint width = mt->width0;
GLuint height = mt->height0;
@ -59,9 +131,9 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
GLuint align_w = 4;
mt->total_height = 0;
intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
if (mt->compressed) {
align_w = intel_compressed_alignment(mt->internal_format);
mt->pitch = ALIGN(width, align_w);
pack_y_pitch = (height + 3) / 4;
} else {

View File

@ -146,7 +146,17 @@ static void recalculate_urb_fence( struct brw_context *brw )
brw->urb.constrained = 0;
if (BRW_IS_G4X(brw)) {
if (BRW_IS_IGDNG(brw)) {
brw->urb.nr_vs_entries = 128;
brw->urb.nr_sf_entries = 48;
if (check_urb_layout(brw)) {
goto done;
} else {
brw->urb.constrained = 1;
brw->urb.nr_vs_entries = limits[VS].preferred_nr_entries;
brw->urb.nr_sf_entries = limits[SF].preferred_nr_entries;
}
} else if (BRW_IS_G4X(brw)) {
brw->urb.nr_vs_entries = 64;
if (check_urb_layout(brw)) {
goto done;

View File

@ -134,7 +134,12 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
c->nr_outputs = 0;
c->first_output = reg;
c->first_overflow_output = 0;
mrf = 4;
if (BRW_IS_IGDNG(c->func.brw))
mrf = 8;
else
mrf = 4;
for (i = 0; i < VERT_RESULT_MAX; i++) {
if (c->prog_data.outputs_written & (1 << i)) {
c->nr_outputs++;
@ -216,7 +221,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
*/
c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
if (BRW_IS_IGDNG(c->func.brw))
c->prog_data.urb_entry_size = (c->nr_outputs + 6 + 3) / 4;
else
c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
c->prog_data.total_grf = reg;
if (INTEL_DEBUG & DEBUG_VS) {
@ -1078,6 +1087,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
struct brw_reg pos = c->regs[PROGRAM_OUTPUT][VERT_RESULT_HPOS];
struct brw_reg ndc;
int eot;
GLuint len_vertext_header = 2;
if (c->key.copy_edgeflag) {
brw_MOV(p,
@ -1096,7 +1106,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
* workaround.
*/
if ((c->prog_data.outputs_written & (1<<VERT_RESULT_PSIZ)) ||
c->key.nr_userclip || !BRW_IS_G4X(p->brw))
c->key.nr_userclip || BRW_IS_965(p->brw))
{
struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD);
GLuint i;
@ -1127,7 +1137,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
* Later, clipping will detect ucp[6] and ensure the primitive is
* clipped against all fixed planes.
*/
if (!BRW_IS_G4X(p->brw)) {
if (BRW_IS_965(p->brw)) {
brw_CMP(p,
vec8(brw_null_reg()),
BRW_CONDITIONAL_L,
@ -1154,7 +1164,21 @@ static void emit_vertex_write( struct brw_vs_compile *c)
*/
brw_set_access_mode(p, BRW_ALIGN_1);
brw_MOV(p, offset(m0, 2), ndc);
brw_MOV(p, offset(m0, 3), pos);
if (BRW_IS_IGDNG(p->brw)) {
/* There are 20 DWs (D0-D19) in VUE vertex header on IGDNG */
brw_MOV(p, offset(m0, 3), pos); /* a portion of vertex header */
/* m4, m5 contain the distances from vertex to the user clip planeXXX.
* Seems it is useless for us.
* m6 is used for aligning, so that the remainder of vertex element is
* reg-aligned.
*/
brw_MOV(p, offset(m0, 7), pos); /* the remainder of vertex element */
len_vertext_header = 6;
} else {
brw_MOV(p, offset(m0, 3), pos);
len_vertext_header = 2;
}
eot = (c->first_overflow_output == 0);
@ -1164,7 +1188,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
c->r0, /* src */
0, /* allocate */
1, /* used */
MIN2(c->nr_outputs + 3, (BRW_MAX_MRF-1)), /* msg len */
MIN2(c->nr_outputs + 1 + len_vertext_header, (BRW_MAX_MRF-1)), /* msg len */
0, /* response len */
eot, /* eot */
1, /* writes complete */

View File

@ -97,7 +97,11 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
* brw_urb_WRITE() results.
*/
vs.thread1.single_program_flow = 0;
vs.thread1.binding_table_entry_count = key->nr_surfaces;
if (BRW_IS_IGDNG(brw))
vs.thread1.binding_table_entry_count = 0; /* hardware requirement */
else
vs.thread1.binding_table_entry_count = key->nr_surfaces;
vs.thread3.urb_entry_read_length = key->urb_entry_read_length;
vs.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
@ -105,10 +109,16 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
vs.thread3.urb_entry_read_offset = 0;
vs.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
vs.thread4.nr_urb_entries = key->nr_urb_entries;
if (BRW_IS_IGDNG(brw))
vs.thread4.nr_urb_entries = key->nr_urb_entries >> 2;
else
vs.thread4.nr_urb_entries = key->nr_urb_entries;
vs.thread4.urb_entry_allocation_size = key->urb_size - 1;
if (BRW_IS_G4X(brw))
if (BRW_IS_IGDNG(brw))
chipset_max_threads = 72;
else if (BRW_IS_G4X(brw))
chipset_max_threads = 32;
else
chipset_max_threads = 16;
@ -120,6 +130,8 @@ vs_unit_create_from_key(struct brw_context *brw, struct brw_vs_unit_key *key)
/* No samplers for ARB_vp programs:
*/
/* It has to be set to 0 for IGDNG
*/
vs.vs5.sampler_count = 0;
if (INTEL_DEBUG & DEBUG_STATS)

View File

@ -714,6 +714,7 @@ static void emit_tex( struct brw_wm_compile *c,
GLuint msgLength, responseLength;
GLuint i, nr;
GLuint emit;
GLuint msg_type;
/* How many input regs are there?
*/
@ -751,6 +752,18 @@ static void emit_tex( struct brw_wm_compile *c,
responseLength = 8; /* always */
if (BRW_IS_IGDNG(p->brw)) {
if (inst->tex_shadow)
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE_IGDNG;
else
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_IGDNG;
} else {
if (inst->tex_shadow)
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE;
else
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE;
}
brw_SAMPLE(p,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
@ -758,12 +771,12 @@ static void emit_tex( struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
inst->writemask,
(inst->tex_shadow ?
BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_COMPARE :
BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE),
msg_type,
responseLength,
msgLength,
0);
0,
1,
BRW_SAMPLER_SIMD_MODE_SIMD16);
}
@ -775,7 +788,7 @@ static void emit_txb( struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
GLuint msgLength;
GLuint msg_type;
/* Shadow ignored for txb.
*/
switch (inst->tex_idx) {
@ -800,6 +813,11 @@ static void emit_txb( struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(8), arg[3]);
msgLength = 9;
if (BRW_IS_IGDNG(p->brw))
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS_IGDNG;
else
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
brw_SAMPLE(p,
retype(vec16(dst[0]), BRW_REGISTER_TYPE_UW),
1,
@ -807,10 +825,12 @@ static void emit_txb( struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(inst->tex_unit),
inst->tex_unit, /* sampler */
inst->writemask,
BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS,
msg_type,
8, /* responseLength */
msgLength,
0);
0,
1,
BRW_SAMPLER_SIMD_MODE_SIMD16);
}

View File

@ -2625,6 +2625,7 @@ static void emit_txb(struct brw_wm_compile *c,
struct brw_reg dst[4], src[4], payload_reg;
GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
GLuint i;
GLuint msg_type;
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
@ -2653,6 +2654,14 @@ static void emit_txb(struct brw_wm_compile *c,
}
brw_MOV(p, brw_message_reg(5), src[3]); /* bias */
brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); /* ref (unused?) */
if (BRW_IS_IGDNG(p->brw)) {
msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_BIAS_IGDNG;
} else {
/* Does it work well on SIMD8? */
msg_type = BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS;
}
brw_SAMPLE(p,
retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
1, /* msg_reg_nr */
@ -2660,10 +2669,12 @@ static void emit_txb(struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(unit),
unit, /* sampler */
inst->DstReg.WriteMask, /* writemask */
BRW_SAMPLER_MESSAGE_SIMD16_SAMPLE_BIAS, /* msg_type */
msg_type, /* msg_type */
4, /* response_length */
4, /* msg_length */
0); /* eot */
0, /* eot */
1,
BRW_SAMPLER_SIMD_MODE_SIMD8);
}
@ -2677,6 +2688,7 @@ static void emit_tex(struct brw_wm_compile *c,
GLuint i, nr;
GLuint emit;
GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
GLuint msg_type;
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
@ -2717,6 +2729,16 @@ static void emit_tex(struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(6), src[2]); /* ref value / R coord */
}
if (BRW_IS_IGDNG(p->brw)) {
if (shadow)
msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_COMPARE_IGDNG;
else
msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE_IGDNG;
} else {
/* Does it work for shadow on SIMD8 ? */
msg_type = BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE;
}
brw_SAMPLE(p,
retype(vec8(dst[0]), BRW_REGISTER_TYPE_UW), /* dest */
1, /* msg_reg_nr */
@ -2724,10 +2746,12 @@ static void emit_tex(struct brw_wm_compile *c,
SURF_INDEX_TEXTURE(unit),
unit, /* sampler */
inst->DstReg.WriteMask, /* writemask */
BRW_SAMPLER_MESSAGE_SIMD8_SAMPLE, /* msg_type */
msg_type, /* msg_type */
4, /* response_length */
shadow ? 6 : 4, /* msg_length */
0); /* eot */
0, /* eot */
1,
BRW_SAMPLER_SIMD_MODE_SIMD8);
if (shadow)
brw_MOV(p, dst[3], brw_imm_f(1.0));

View File

@ -71,7 +71,9 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
key->max_threads = 1;
else {
/* WM maximum threads is number of EUs times number of threads per EU. */
if (BRW_IS_G4X(brw))
if (BRW_IS_IGDNG(brw))
key->max_threads = 12 * 6;
else if (BRW_IS_G4X(brw))
key->max_threads = 10 * 5;
else
key->max_threads = 8 * 4;
@ -141,7 +143,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
wm.thread0.kernel_start_pointer = brw->wm.prog_bo->offset >> 6; /* reloc */
wm.thread1.depth_coef_urb_read_offset = 1;
wm.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
wm.thread1.binding_table_entry_count = key->nr_surfaces;
if (BRW_IS_IGDNG(brw))
wm.thread1.binding_table_entry_count = 0; /* hardware requirement */
else
wm.thread1.binding_table_entry_count = key->nr_surfaces;
if (key->total_scratch != 0) {
wm.thread2.scratch_space_base_pointer =
@ -158,7 +164,11 @@ wm_unit_create_from_key(struct brw_context *brw, struct brw_wm_unit_key *key,
wm.thread3.const_urb_entry_read_length = key->curb_entry_read_length;
wm.thread3.const_urb_entry_read_offset = key->curbe_offset * 2;
wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
if (BRW_IS_IGDNG(brw))
wm.wm4.sampler_count = 0; /* hardware requirement */
else
wm.wm4.sampler_count = (key->sampler_count + 1) / 4;
if (brw->wm.sampler_bo != NULL) {
/* reloc */
wm.wm4.sampler_state_pointer = brw->wm.sampler_bo->offset >> 5;

View File

@ -67,13 +67,18 @@
#define PCI_CHIP_G45_G 0x2E22
#define PCI_CHIP_G41_G 0x2E32
#define PCI_CHIP_ILD_G 0x0042
#define PCI_CHIP_ILM_G 0x0046
#define IS_MOBILE(devid) (devid == PCI_CHIP_I855_GM || \
devid == PCI_CHIP_I915_GM || \
devid == PCI_CHIP_I945_GM || \
devid == PCI_CHIP_I945_GME || \
devid == PCI_CHIP_I965_GM || \
devid == PCI_CHIP_I965_GME || \
devid == PCI_CHIP_GM45_GM || IS_IGD(devid))
devid == PCI_CHIP_GM45_GM || \
IS_IGD(devid) || \
devid == PCI_CHIP_ILM_G)
#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \
devid == PCI_CHIP_Q45_G || \
@ -82,6 +87,10 @@
#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM)
#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid))
#define IS_ILD(devid) (devid == PCI_CHIP_ILD_G)
#define IS_ILM(devid) (devid == PCI_CHIP_ILM_G)
#define IS_IGDNG(devid) (IS_ILD(devid) || IS_ILM(devid))
#define IS_915(devid) (devid == PCI_CHIP_I915_G || \
devid == PCI_CHIP_E7221_G || \
devid == PCI_CHIP_I915_GM)
@ -99,7 +108,8 @@
devid == PCI_CHIP_I965_GM || \
devid == PCI_CHIP_I965_GME || \
devid == PCI_CHIP_I946_GZ || \
IS_G4X(devid))
IS_G4X(devid) || \
IS_IGDNG(devid))
#define IS_9XX(devid) (IS_915(devid) || \
IS_945(devid) || \

View File

@ -161,6 +161,12 @@ intelGetString(GLcontext * ctx, GLenum name)
case PCI_CHIP_G41_G:
chipset = "Intel(R) G41";
break;
case PCI_CHIP_ILD_G:
chipset = "Intel(R) IGDNG_D";
break;
case PCI_CHIP_ILM_G:
chipset = "Intel(R) IGDNG_M";
break;
default:
chipset = "Unknown Intel Chipset";
break;

View File

@ -353,23 +353,31 @@ intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
}
void
intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint level, GLuint img,
GLuint x, GLuint y)
intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt,
GLuint level, GLuint img,
GLuint x, GLuint y,
GLuint offset)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
assert(img < mt->level[level].nr_images);
mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp;
mt->level[level].image_offset[img] = (x + y * mt->pitch) * mt->cpp + offset;
DBG("%s level %d img %d pos %d,%d image_offset %x\n",
__FUNCTION__, level, img, x, y, mt->level[level].image_offset[img]);
}
void
intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint level, GLuint img,
GLuint x, GLuint y)
{
intel_miptree_set_image_offset_ex(mt, level, img, x, y, 0);
}
/* Although we use the image_offset[] array to store relative offsets
* to cube faces, Mesa doesn't know anything about this and expects
@ -483,7 +491,7 @@ intel_miptree_image_data(struct intel_context *intel,
}
}
extern GLuint intel_compressed_alignment(GLenum);
extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *);
/* Copy mipmap image between trees
*/
void
@ -503,9 +511,11 @@ intel_miptree_image_copy(struct intel_context *intel,
GLboolean success;
if (dst->compressed) {
GLuint alignment = intel_compressed_alignment(dst->internal_format);
GLuint align_w, align_h;
intel_get_texture_alignment_unit(dst->internal_format, &align_w, &align_h);
height = (height + 3) / 4;
width = ((width + alignment - 1) & ~(alignment - 1));
width = ALIGN(width, align_w);
}
for (i = 0; i < depth; i++) {

View File

@ -196,6 +196,11 @@ void intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
GLuint x, GLuint y,
GLuint w, GLuint h, GLuint d);
void intel_miptree_set_image_offset_ex(struct intel_mipmap_tree *mt,
GLuint level,
GLuint img, GLuint x, GLuint y,
GLuint offset);
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
GLuint level,
GLuint img, GLuint x, GLuint y);

View File

@ -35,28 +35,39 @@
#include "intel_context.h"
#include "main/macros.h"
GLuint intel_compressed_alignment(GLenum internalFormat)
void intel_get_texture_alignment_unit(GLenum internalFormat, GLuint *w, GLuint *h)
{
GLuint alignment = 4;
switch (internalFormat) {
case GL_COMPRESSED_RGB_FXT1_3DFX:
case GL_COMPRESSED_RGBA_FXT1_3DFX:
alignment = 8;
*w = 8;
*h = 4;
break;
case GL_RGB_S3TC:
case GL_RGB4_S3TC:
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_RGBA_S3TC:
case GL_RGBA4_S3TC:
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
*w = 4;
*h = 4;
break;
default:
*w = 4;
*h = 2;
break;
}
return alignment;
}
void i945_miptree_layout_2d( struct intel_context *intel,
struct intel_mipmap_tree *mt,
uint32_t tiling )
{
GLint align_h = 2, align_w = 4;
GLuint align_h = 2, align_w = 4;
GLuint level;
GLuint x = 0;
GLuint y = 0;
@ -64,9 +75,9 @@ void i945_miptree_layout_2d( struct intel_context *intel,
GLuint height = mt->height0;
mt->pitch = mt->width0;
intel_get_texture_alignment_unit(mt->internal_format, &align_w, &align_h);
if (mt->compressed) {
align_w = intel_compressed_alignment(mt->internal_format);
mt->pitch = ALIGN(mt->width0, align_w);
}

View File

@ -41,4 +41,4 @@ static GLuint minify( GLuint d )
extern void i945_miptree_layout_2d(struct intel_context *intel,
struct intel_mipmap_tree *mt,
uint32_t tiling);
extern GLuint intel_compressed_alignment(GLenum);
extern void intel_get_texture_alignment_unit(GLenum, GLuint *, GLuint *);