diff options
Diffstat (limited to 'src/gallium')
36 files changed, 528 insertions, 957 deletions
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index dbbc33fffa..f2368dde5c 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -114,6 +114,12 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, #endif for (slot = 0; slot < shader->info.num_inputs; slot++) { +#if 0 + assert(!util_is_inf_or_nan(input[slot][0])); + assert(!util_is_inf_or_nan(input[slot][1])); + assert(!util_is_inf_or_nan(input[slot][2])); + assert(!util_is_inf_or_nan(input[slot][3])); +#endif machine->Inputs[slot].xyzw[0].f[j] = input[slot][0]; machine->Inputs[slot].xyzw[1].f[j] = input[slot][1]; machine->Inputs[slot].xyzw[2].f[j] = input[slot][2]; diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c index 4da833c25e..93f752faec 100644 --- a/src/gallium/drivers/nv04/nv04_miptree.c +++ b/src/gallium/drivers/nv04/nv04_miptree.c @@ -31,7 +31,8 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt) for (l = 0; l <= pt->last_level; l++) { - nv04mt->level[l].image_offset = offset; + nv04mt->level[l].image_offset = + CALLOC(nr_faces, sizeof(unsigned)); offset += nv04mt->level[l].pitch * pt->height[l]; } diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h index 0d51439e3f..399f750dbe 100644 --- a/src/gallium/drivers/nv04/nv04_state.h +++ b/src/gallium/drivers/nv04/nv04_state.h @@ -37,7 +37,7 @@ struct nv04_miptree { struct { uint pitch; - uint image_offset; + uint *image_offset; } level[PIPE_MAX_TEXTURE_LEVELS]; }; diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 6bdf544a05..a4e89c37d1 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -34,10 +34,6 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); int i; - if (r300->dirty_state) { - r300_emit_dirty_state(r300); - } - for (i = 0; i < r300->vertex_buffer_count; i++) { void* buf = pipe_buffer_map(pipe->screen, r300->vertex_buffers[i].buffer, diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 6f62998b35..96f1f11246 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -264,6 +264,11 @@ struct r300_context { /* Draw module. Used mostly for SW TCL. */ struct draw_context* draw; + /* Vertex buffer for rendering. */ + struct pipe_buffer* vbo; + /* Offset into the VBO. */ + size_t vbo_offset; + /* Various CSO state objects. */ /* Blend state. */ struct r300_blend_state* blend_state; @@ -289,7 +294,7 @@ struct r300_context { /* Texture states. */ struct r300_texture* textures[8]; int texture_count; - /* Vertex buffers. */ + /* Vertex buffers for Gallium. */ struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; int vertex_buffer_count; /* Vertex information. */ diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c index dd63136c9d..1ff72172eb 100644 --- a/src/gallium/drivers/r300/r300_debug.c +++ b/src/gallium/drivers/r300/r300_debug.c @@ -30,81 +30,6 @@ static void r300_dump_fs(struct r300_fragment_shader* fs) } } -static char* r500_fs_swiz[] = { - " R", - " G", - " B", - " A", - " 0", - ".5", - " 1", - " U", -}; - -static char* r500_fs_op_rgb[] = { - "MAD", - "DP3", - "DP4", - "D2A", - "MIN", - "MAX", - "---", - "CND", - "CMP", - "FRC", - "SOP", - "MDH", - "MDV", -}; - -static char* r500_fs_op_alpha[] = { - "MAD", - " DP", - "MIN", - "MAX", - "---", - "CND", - "CMP", - "FRC", - "EX2", - "LN2", - "RCP", - "RSQ", - "SIN", - "COS", - "MDH", - "MDV", -}; - -static char* r500_fs_mask[] = { - "NONE", - "R ", - " G ", - "RG ", - " B ", - "R B ", - " GB ", - "RGB ", - " A", - "R A", - " G A", - "RG A", - " BA", - "R BA", - " GBA", - "RGBA", -}; - -static char* r500_fs_tex[] = { - " NOP", - " LD", - "TEXKILL", - " PROJ", - "LODBIAS", - " LOD", - " DXDY", -}; - void r500_fs_dump(struct r500_fragment_shader* fs) { int i; @@ -225,12 +150,25 @@ void r500_fs_dump(struct r500_fragment_shader* fs) } } +static void r300_vs_op_dump(uint32_t op) +{ + if (op & 0x81) { + debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n"); + } else if (op & 0x80) { + debug_printf(" PVS_MACRO_OP_2CLK_MADD\n"); + } else if (op & 0x40) { + debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]); + } else { + debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]); + } +} + void r300_vs_dump(struct r300_vertex_shader* vs) { int i; for (i = 0; i < vs->instruction_count; i++) { - debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0); + r300_vs_op_dump(vs->instructions[i].inst0); debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1); debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2); debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3); diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h index a1f873656d..6306594099 100644 --- a/src/gallium/drivers/r300/r300_debug.h +++ b/src/gallium/drivers/r300/r300_debug.h @@ -27,6 +27,152 @@ #include "r300_state_shader.h" #include "r300_state_tcl.h" +static char* r500_fs_swiz[] = { + " R", + " G", + " B", + " A", + " 0", + ".5", + " 1", + " U", +}; + +static char* r500_fs_op_rgb[] = { + "MAD", + "DP3", + "DP4", + "D2A", + "MIN", + "MAX", + "---", + "CND", + "CMP", + "FRC", + "SOP", + "MDH", + "MDV", +}; + +static char* r500_fs_op_alpha[] = { + "MAD", + " DP", + "MIN", + "MAX", + "---", + "CND", + "CMP", + "FRC", + "EX2", + "LN2", + "RCP", + "RSQ", + "SIN", + "COS", + "MDH", + "MDV", +}; + +static char* r500_fs_mask[] = { + "NONE", + "R ", + " G ", + "RG ", + " B ", + "R B ", + " GB ", + "RGB ", + " A", + "R A", + " G A", + "RG A", + " BA", + "R BA", + " GBA", + "RGBA", +}; + +static char* r500_fs_tex[] = { + " NOP", + " LD", + "TEXKILL", + " PROJ", + "LODBIAS", + " LOD", + " DXDY", +}; + +static char* r300_vs_ve_ops[] = { + /* R300 vector ops */ + " VE_NO_OP", + " VE_DOT_PRODUCT", + " VE_MULTIPLY", + " VE_ADD", + " VE_MULTIPLY_ADD", + " VE_DISTANCE_FACTOR", + " VE_FRACTION", + " VE_MAXIMUM", + " VE_MINIMUM", + "VE_SET_GREATER_THAN_EQUAL", + " VE_SET_LESS_THAN", + " VE_MULTIPLYX2_ADD", + " VE_MULTIPLY_CLAMP", + " VE_FLT2FIX_DX", + " VE_FLT2FIX_DX_RND", + /* R500 vector ops */ + " VE_PRED_SET_EQ_PUSH", + " VE_PRED_SET_GT_PUSH", + " VE_PRED_SET_GTE_PUSH", + " VE_PRED_SET_NEQ_PUSH", + " VE_COND_WRITE_EQ", + " VE_COND_WRITE_GT", + " VE_COND_WRITE_GTE", + " VE_COND_WRITE_NEQ", + " VE_SET_GREATER_THAN", + " VE_SET_EQUAL", + " VE_SET_NOT_EQUAL", + " (reserved)", + " (reserved)", + " (reserved)", +}; + +static char* r300_vs_me_ops[] = { + /* R300 math ops */ + " ME_NO_OP", + " ME_EXP_BASE2_DX", + " ME_LOG_BASE2_DX", + " ME_EXP_BASEE_FF", + " ME_LIGHT_COEFF_DX", + " ME_POWER_FUNC_FF", + " ME_RECIP_DX", + " ME_RECIP_FF", + " ME_RECIP_SQRT_DX", + " ME_RECIP_SQRT_FF", + " ME_MULTIPLY", + " ME_EXP_BASE2_FULL_DX", + " ME_LOG_BASE2_FULL_DX", + " ME_POWER_FUNC_FF_CLAMP_B", + "ME_POWER_FUNC_FF_CLAMP_B1", + "ME_POWER_FUNC_FF_CLAMP_01", + " ME_SIN", + " ME_COS", + /* R500 math ops */ + " ME_LOG_BASE2_IEEE", + " ME_RECIP_IEEE", + " ME_RECIP_SQRT_IEEE", + " ME_PRED_SET_EQ", + " ME_PRED_SET_GT", + " ME_PRED_SET_GTE", + " ME_PRED_SET_NEQ", + " ME_PRED_SET_CLR", + " ME_PRED_SET_INV", + " ME_PRED_SET_POP", + " ME_PRED_SET_RESTORE", + " (reserved)", + " (reserved)", + " (reserved)", +}; + void r500_fs_dump(struct r500_fragment_shader* fs); void r300_vs_dump(struct r300_vertex_shader* vs); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 01bac5f759..c73d5a0b44 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -296,6 +296,30 @@ void r300_emit_texture(struct r300_context* r300, END_CS; } +void r300_emit_vertex_buffer(struct r300_context* r300) +{ + CS_LOCALS(r300); + + debug_printf("r300: Preparing vertex buffer %p for render, " + "vertex size %d\n", r300->vbo, + r300->vertex_info.vinfo.size); + /* Set the pointer to our vertex buffer. The emitted values are this: + * PACKET3 [3D_LOAD_VBPNTR] + * COUNT [1] + * FORMAT [size | stride << 8] + * OFFSET [offset into BO] + * VBPNTR [relocated BO] + */ + BEGIN_CS(7); + OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); + OUT_CS(1); + OUT_CS(r300->vertex_info.vinfo.size | + (r300->vertex_info.vinfo.size << 8)); + OUT_CS(r300->vbo_offset); + OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); + END_CS; +} + void r300_emit_vertex_format_state(struct r300_context* r300) { int i; @@ -421,20 +445,41 @@ void r300_flush_textures(struct r300_context* r300) void r300_emit_dirty_state(struct r300_context* r300) { struct r300_screen* r300screen = r300_screen(r300->context.screen); + struct r300_texture* tex; int i; int dirty_tex = 0; - if (!(r300->dirty_hw)) { + if (!(r300->dirty_state)) { return; } r300_update_derived_state(r300); /* XXX check size */ - struct r300_texture* fb_tex = - (struct r300_texture*)r300->framebuffer_state.cbufs[0]; - r300->winsys->add_buffer(r300->winsys, fb_tex->buffer, - 0, RADEON_GEM_DOMAIN_VRAM); + /* Color buffers... */ + for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) { + tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture; + assert(tex && tex->buffer && "cbuf is marked, but NULL!"); + if (!tex->buffer) return; + r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM); + } + /* ...depth buffer... */ + if (r300->framebuffer_state.zsbuf) { + tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture; + assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); + if (!tex->buffer) return; + r300->winsys->add_buffer(r300->winsys, tex->buffer, + 0, RADEON_GEM_DOMAIN_VRAM); + } + /* ...and vertex buffer. */ + if (r300->vbo) { + r300->winsys->add_buffer(r300->winsys, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0); + } else { + debug_printf("No VBO while emitting dirty state!\n"); + } + if (r300->winsys->validate(r300->winsys)) { /* XXX */ r300->context.flush(&r300->context, 0, NULL); @@ -519,4 +564,9 @@ void r300_emit_dirty_state(struct r300_context* r300) r300_emit_vertex_format_state(r300); r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT; } + + /* Finally, emit the VBO. */ + r300_emit_vertex_buffer(r300); + + r300->dirty_hw++; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 31dbc7ab85..36e14f69f7 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -62,6 +62,8 @@ void r300_emit_scissor_state(struct r300_context* r300, void r300_emit_texture(struct r300_context* r300, struct r300_texture* tex, unsigned offset); +void r300_emit_vertex_buffer(struct r300_context* r300); + void r300_emit_vertex_format_state(struct r300_context* r300); void r300_emit_vertex_shader(struct r300_context* r300, diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index cbd84d7c56..29b66cee7e 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -180,27 +180,10 @@ static void prepare_render(struct r300_render* render, unsigned count) CS_LOCALS(r300); - /* Make sure that all possible state is emitted. */ - r300_emit_dirty_state(r300); + r300->vbo = render->vbo; + r300->vbo_offset = render->vbo_offset; - debug_printf("r300: Preparing vertex buffer %p for render, " - "vertex size %d, vertex count %d\n", render->vbo, - r300->vertex_info.vinfo.size, count); - /* Set the pointer to our vertex buffer. The emitted values are this: - * PACKET3 [3D_LOAD_VBPNTR] - * COUNT [1] - * FORMAT [size | stride << 8] - * OFFSET [0] - * VBPNTR [relocated BO] - */ - BEGIN_CS(7); - OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); - OUT_CS(1); - OUT_CS(r300->vertex_info.vinfo.size | - (r300->vertex_info.vinfo.size << 8)); - OUT_CS(render->vbo_offset); - OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); - END_CS; + r300_emit_dirty_state(r300); } static void r300_render_draw_arrays(struct vbuf_render* render, diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 184a23c9e6..2118f7706f 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -289,6 +289,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe, /* Copy state directly into shader. */ fs->state = *shader; + fs->state.tokens = tgsi_dup_tokens(shader->tokens); tgsi_scan_shader(shader->tokens, &fs->info); @@ -317,6 +318,8 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) /* Delete fragment shader state. */ static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) { + struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; + FREE(fs->state.tokens); FREE(shader); } @@ -562,14 +565,17 @@ static void r300_set_viewport_state(struct pipe_context* pipe, r300->viewport_state->vte_control = R300_VTX_W0_FMT; if (state->scale[0] != 1.0f) { + assert(state->scale[0] != 0.0f); r300->viewport_state->xscale = state->scale[0]; r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA; } if (state->scale[1] != 1.0f) { + assert(state->scale[1] != 0.0f); r300->viewport_state->yscale = state->scale[1]; r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA; } if (state->scale[2] != 1.0f) { + assert(state->scale[2] != 0.0f); r300->viewport_state->zscale = state->scale[2]; r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA; } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index c4c9784a00..caa5f3b543 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -162,26 +162,40 @@ static void r300_vs_tab_routes(struct r300_context* r300, static void r300_vertex_psc(struct r300_context* r300, struct r300_vertex_format* vformat) { + struct r300_screen* r300screen = r300_screen(r300->context.screen); struct vertex_info* vinfo = &vformat->vinfo; int* tab = vformat->vs_tab; uint32_t temp; - int i; + int i, attrib_count; - debug_printf("r300: attrib count: %d\n", vinfo->num_attribs); - for (i = 0; i < vinfo->num_attribs; i++) { - debug_printf("r300: attrib: offset %d, interp %d, size %d," - " tab %d\n", vinfo->attrib[i].src_index, - vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, - tab[i]); + /* Vertex shaders have no semantics on their inputs, + * so PSC should just route stuff based on their info, + * and not on attrib information. */ + if (r300screen->caps->has_tcl) { + attrib_count = r300->vs->info.num_inputs; + debug_printf("r300: routing %d attribs in psc for vs\n", + attrib_count); + } else { + attrib_count = vinfo->num_attribs; + debug_printf("r300: attrib count: %d\n", attrib_count); + for (i = 0; i < attrib_count; i++) { + debug_printf("r300: attrib: offset %d, interp %d, size %d," + " tab %d\n", vinfo->attrib[i].src_index, + vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit, + tab[i]); + } } - for (i = 0; i < vinfo->num_attribs; i++) { + for (i = 0; i < attrib_count; i++) { /* Make sure we have a proper destination for our attribute */ assert(tab[i] != -1); /* Add the attribute to the PSC table. */ - temp = translate_vertex_data_type(vinfo->attrib[i].emit) | - (tab[i] << R300_DST_VEC_LOC_SHIFT); + temp = r300screen->caps->has_tcl ? + R300_DATA_TYPE_FLOAT_4 : + translate_vertex_data_type(vinfo->attrib[i].emit); + temp |= tab[i] << R300_DST_VEC_LOC_SHIFT; + if (i & 1) { vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff; vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16; @@ -206,7 +220,6 @@ static void r300_vertex_psc(struct r300_context* r300, /* Update the vertex format. */ static void r300_update_vertex_format(struct r300_context* r300) { - struct r300_screen* r300screen = r300_screen(r300->context.screen); struct r300_vertex_format vformat; int i; diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c index d84912de48..ed9164db49 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.c +++ b/src/gallium/drivers/r300/r300_state_tcl.c @@ -71,16 +71,13 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, { switch (src->File) { case TGSI_FILE_NULL: - /* Probably a zero or one swizzle */ - return R300_PVS_SRC_REG_INPUT; - break; case TGSI_FILE_INPUT: + /* Probably a zero or one swizzle */ return R300_PVS_SRC_REG_INPUT; - break; case TGSI_FILE_TEMPORARY: return R300_PVS_SRC_REG_TEMPORARY; - break; case TGSI_FILE_CONSTANT: + case TGSI_FILE_IMMEDIATE: return R300_PVS_SRC_REG_CONSTANT; default: debug_printf("r300: vs: Unimplemented src type %d\n", src->File); @@ -89,16 +86,32 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler, return 0; } +static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler, + struct tgsi_src_register* src) +{ + switch (src->File) { + case TGSI_FILE_NULL: + case TGSI_FILE_INPUT: + case TGSI_FILE_TEMPORARY: + case TGSI_FILE_CONSTANT: + return src->Index; + case TGSI_FILE_IMMEDIATE: + return src->Index + assembler->imm_offset; + default: + debug_printf("r300: vs: Unimplemented src type %d\n", src->File); + break; + } + return 0; +} + static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler, struct tgsi_dst_register* dst) { switch (dst->File) { case TGSI_FILE_TEMPORARY: return R300_PVS_DST_REG_TEMPORARY; - break; case TGSI_FILE_OUTPUT: return R300_PVS_DST_REG_OUT; - break; default: debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File); break; @@ -112,10 +125,8 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler, switch (dst->File) { case TGSI_FILE_TEMPORARY: return dst->Index; - break; case TGSI_FILE_OUTPUT: return assembler->tab[dst->Index]; - break; default: debug_printf("r300: vs: Unimplemented dst %d\n", dst->File); break; @@ -135,6 +146,12 @@ static uint32_t r300_vs_op(unsigned op) case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: return R300_VE_ADD; + case TGSI_OPCODE_MAX: + return R300_VE_MAXIMUM; + case TGSI_OPCODE_SLT: + return R300_VE_SET_LESS_THAN; + case TGSI_OPCODE_RSQ: + return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX; case TGSI_OPCODE_MAD: return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD; default: @@ -158,39 +175,62 @@ static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg) } } +/* XXX icky icky icky icky */ +static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg) +{ + if (reg->SrcRegister.Extended) { + return reg->SrcRegisterExtSwz.ExtSwizzleX | + (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) | + (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) | + (reg->SrcRegisterExtSwz.ExtSwizzleX << 9); + } else { + return reg->SrcRegister.SwizzleX | + (reg->SrcRegister.SwizzleX << 3) | + (reg->SrcRegister.SwizzleX << 6) | + (reg->SrcRegister.SwizzleX << 9); + } +} + +/* XXX scalar stupidity */ static void r300_vs_emit_inst(struct r300_vertex_shader* vs, struct r300_vs_asm* assembler, struct tgsi_full_src_register* src, struct tgsi_full_dst_register* dst, unsigned op, - unsigned count) + unsigned count, + boolean is_scalar) { int i = vs->instruction_count; vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) | R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) | R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) | - R300_PVS_DST_WE_XYZW; + R300_PVS_DST_WE(dst->DstRegister.WriteMask); switch (count) { case 3: vs->instructions[i].inst3 = R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, &src[2].SrcRegister)) | - R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) | + R300_PVS_SRC_OFFSET(r300_vs_src(assembler, + &src[2].SrcRegister)) | R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2])); /* Fall through */ case 2: vs->instructions[i].inst2 = R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, &src[1].SrcRegister)) | - R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) | + R300_PVS_SRC_OFFSET(r300_vs_src(assembler, + &src[1].SrcRegister)) | R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1])); /* Fall through */ case 1: vs->instructions[i].inst1 = R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler, &src[0].SrcRegister)) | - R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) | - R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0])); + R300_PVS_SRC_OFFSET(r300_vs_src(assembler, + &src[0].SrcRegister)) | + /* XXX the icky, it burns */ + R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0]) + : r300_vs_swiz(&src[0])); break; } vs->instruction_count++; @@ -201,11 +241,18 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs, struct tgsi_full_instruction* inst) { switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_RSQ: + r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, + &inst->FullDstRegisters[0], inst->Instruction.Opcode, + 1, TRUE); + break; case TGSI_OPCODE_ADD: case TGSI_OPCODE_MUL: + case TGSI_OPCODE_MAX: + case TGSI_OPCODE_SLT: r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2); + 2, FALSE); break; case TGSI_OPCODE_DP3: /* Set alpha swizzle to zero for src0 and src1 */ @@ -235,19 +282,19 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs, case TGSI_OPCODE_DP4: r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2); + 2, FALSE); break; case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: inst->FullSrcRegisters[1] = r300_constant_zero; r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 2); + 2, FALSE); break; case TGSI_OPCODE_MAD: r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters, &inst->FullDstRegisters[0], inst->Instruction.Opcode, - 3); + 3, FALSE); break; case TGSI_OPCODE_END: break; diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h index e2e1357d43..d5d425e9d6 100644 --- a/src/gallium/drivers/r300/r300_state_tcl.h +++ b/src/gallium/drivers/r300/r300_state_tcl.h @@ -35,6 +35,10 @@ # define R300_VE_DOT_PRODUCT 1 # define R300_VE_MULTIPLY 2 # define R300_VE_ADD 3 +# define R300_VE_MAXIMUM 7 +# define R300_VE_SET_LESS_THAN 10 +#define R300_PVS_DST_MATH_INST (1 << 6) +# define R300_ME_RECIP_DX 6 #define R300_PVS_DST_MACRO_INST (1 << 7) # define R300_PVS_MACRO_OP_2CLK_MADD 0 #define R300_PVS_DST_REG_TYPE(x) ((x) << 8) diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c index 4dd5b8af99..3198c97378 100644 --- a/src/gallium/drivers/r300/r300_surface.c +++ b/src/gallium/drivers/r300/r300_surface.c @@ -23,19 +23,17 @@ #include "r300_surface.h" -static void r300_surface_setup(struct pipe_context* pipe, - struct pipe_surface* dest, +static void r300_surface_setup(struct r300_context* r300, + struct r300_texture* dest, unsigned x, unsigned y, unsigned w, unsigned h) { - struct r300_context* r300 = r300_context(pipe); - struct r300_capabilities* caps = r300_screen(pipe->screen)->caps; - struct r300_texture* tex = (struct r300_texture*)dest->texture; - unsigned pixpitch = tex->stride / tex->tex.block.size; + struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps; + unsigned pixpitch = dest->stride / dest->tex.block.size; CS_LOCALS(r300); /* Make sure our target BO is okay. */ - r300->winsys->add_buffer(r300->winsys, tex->buffer, + r300->winsys->add_buffer(r300->winsys, dest->buffer, 0, RADEON_GEM_DOMAIN_VRAM); if (r300->winsys->validate(r300->winsys)) { r300->context.flush(&r300->context, 0, NULL); @@ -71,9 +69,9 @@ static void r300_surface_setup(struct pipe_context* pipe, /* Setup colorbuffer. */ OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); - OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch | - r300_translate_colorformat(tex->tex.format)); + r300_translate_colorformat(dest->tex.format)); OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf); END_CS; @@ -110,7 +108,7 @@ static void r300_surface_fill(struct pipe_context* pipe, return; } - r300_surface_setup(r300, dest, x, y, w, h); + r300_surface_setup(r300, tex, x, y, w, h); /* Vertex shader setup */ if (caps->has_tcl) { @@ -227,6 +225,8 @@ static void r300_surface_copy(struct pipe_context* pipe, srcx, srcy, w, h); } + r300_surface_setup(r300, desttex, destx, desty, w, h); + r300_emit_sampler(r300, &r300_sampler_copy_state, 0); r300_emit_texture(r300, srctex, 0); r300_flush_textures(r300); diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index fe91f4e184..5ea9f56247 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -86,8 +86,6 @@ static struct pipe_texture* r300_texture_create(struct pipe_screen* screen, const struct pipe_texture* template) { - /* XXX struct r300_screen* r300screen = r300_screen(screen); */ - struct r300_texture* tex = CALLOC_STRUCT(r300_texture); if (!tex) { diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 82e23c413c..47c24f3086 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -132,6 +132,7 @@ enum pipe_texture_target { #define PIPE_TEX_FACE_NEG_Y 3 #define PIPE_TEX_FACE_POS_Z 4 #define PIPE_TEX_FACE_NEG_Z 5 +#define PIPE_TEX_FACE_MAX 6 #define PIPE_TEX_WRAP_REPEAT 0 #define PIPE_TEX_WRAP_CLAMP 1 @@ -158,14 +159,6 @@ enum pipe_texture_target { #define PIPE_TEX_COMPARE_NONE 0 #define PIPE_TEX_COMPARE_R_TO_TEXTURE 1 -#define PIPE_TEX_FACE_POS_X 0 -#define PIPE_TEX_FACE_NEG_X 1 -#define PIPE_TEX_FACE_POS_Y 2 -#define PIPE_TEX_FACE_NEG_Y 3 -#define PIPE_TEX_FACE_POS_Z 4 -#define PIPE_TEX_FACE_NEG_Z 5 -#define PIPE_TEX_FACE_MAX 6 - #define PIPE_TEXTURE_USAGE_RENDER_TARGET 0x1 #define PIPE_TEXTURE_USAGE_DISPLAY_TARGET 0x2 /* ie a backbuffer */ #define PIPE_TEXTURE_USAGE_PRIMARY 0x4 /* ie a frontbuffer */ diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/fakeglx.c index 65e7048188..85e7ecfb9e 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.c +++ b/src/gallium/state_trackers/glx/xlib/fakeglx.c @@ -97,6 +97,9 @@ struct fake_glx_context { +#define DEFAULT_DIRECT GL_TRUE + + /**********************************************************************/ /*** GLX Visual Code ***/ /**********************************************************************/ @@ -1059,7 +1062,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ @@ -1296,9 +1299,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) static Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx ) { - (void) dpy; + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; (void) ctx; - return False; + return glxCtx->glxContext.isDirect; } @@ -2055,7 +2058,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ @@ -2277,7 +2280,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index a3d1651653..79c2230588 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -1100,26 +1100,19 @@ XMesaContext XMesaGetCurrentContext( void ) - - - -/* - * Copy the back buffer to the front buffer. If there's no back buffer - * this is a no-op. +/** + * Swap front and back color buffers and have winsys display front buffer. + * If there's no front color buffer no swap actually occurs. */ PUBLIC void XMesaSwapBuffers( XMesaBuffer b ) { - struct pipe_surface *surf; + struct pipe_surface *frontLeftSurf; - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - st_notify_swapbuffers(b->stfb); + st_swapbuffers(b->stfb, &frontLeftSurf, NULL); - st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - driver.display_surface(b, surf); + if (frontLeftSurf) { + driver.display_surface(b, frontLeftSurf); } xmesa_check_and_update_buffer_size(NULL, b); diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile index f8c8135854..6c9cbef26d 100644 --- a/src/gallium/winsys/drm/nouveau/Makefile +++ b/src/gallium/winsys/drm/nouveau/Makefile @@ -2,7 +2,7 @@ TOP = ../../../../.. include $(TOP)/configs/current -SUBDIRS = drm dri dri2 +SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS) default install clean: @for dir in $(SUBDIRS) ; do \ diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile index f7db6201fe..024ab150cb 100644 --- a/src/gallium/winsys/drm/nouveau/dri/Makefile +++ b/src/gallium/winsys/drm/nouveau/dri/Makefile @@ -3,9 +3,8 @@ include $(TOP)/configs/current LIBNAME = nouveau_dri.so -MINIGLX_SOURCES = - PIPE_DRIVERS = \ + $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ $(TOP)/src/gallium/drivers/nv04/libnv04.a \ $(TOP)/src/gallium/drivers/nv10/libnv10.a \ @@ -13,22 +12,15 @@ PIPE_DRIVERS = \ $(TOP)/src/gallium/drivers/nv30/libnv30.a \ $(TOP)/src/gallium/drivers/nv40/libnv40.a \ $(TOP)/src/gallium/drivers/nv50/libnv50.a - -DRIVER_SOURCES = \ - nouveau_context.c \ - nouveau_screen.c \ - nouveau_swapbuffers.c \ - nouveau_lock.c + +DRIVER_SOURCES = C_SOURCES = \ $(COMMON_GALLIUM_SOURCES) \ $(DRIVER_SOURCES) -ASM_SOURCES = +include ../../Makefile.template -DRIVER_DEFINES = $(shell pkg-config libdrm_nouveau --cflags) DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) -include ../../Makefile.template - symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c deleted file mode 100644 index deb6ffcff1..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c +++ /dev/null @@ -1,118 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> -#include <utils.h> - -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/drm_api.h> -#include <pipe/p_defines.h> -#include <pipe/p_context.h> -#include <pipe/p_screen.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" - -#include "nouveau_drmif.h" - -GLboolean -nouveau_context_create(const __GLcontextModes *glVis, - __DRIcontextPrivate *driContextPriv, - void *sharedContextPrivate) -{ - __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv; - struct nouveau_screen *nv_screen = driScrnPriv->private; - struct nouveau_context *nv; - struct pipe_context *pipe; - struct st_context *st_share = NULL; - - if (sharedContextPrivate) - st_share = ((struct nouveau_context *)sharedContextPrivate)->st; - - nv = CALLOC_STRUCT(nouveau_context); - if (!nv) - return GL_FALSE; - - { - struct nouveau_device_priv *nvdev = - nouveau_device(nv_screen->device); - - nvdev->ctx = driContextPriv->hHWContext; - nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock; - } - - pipe = drm_api_hooks.create_context(nv_screen->pscreen); - if (!pipe) { - FREE(nv); - return GL_FALSE; - } - pipe->priv = nv; - - driContextPriv->driverPrivate = nv; - nv->dri_screen = driScrnPriv; - - driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache, - nv->dri_screen->myNum, "nouveau"); - - nv->st = st_create_context(pipe, glVis, st_share); - return GL_TRUE; -} - -void -nouveau_context_destroy(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - - assert(nv); - - st_finish(nv->st); - st_destroy_context(nv->st); - - FREE(nv); -} - -GLboolean -nouveau_context_bind(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) -{ - struct nouveau_context *nv; - struct nouveau_framebuffer *draw, *read; - - if (!driContextPriv) { - st_make_current(NULL, NULL, NULL); - return GL_TRUE; - } - - nv = driContextPriv->driverPrivate; - draw = driDrawPriv->driverPrivate; - read = driReadPriv->driverPrivate; - - st_make_current(nv->st, draw->stfb, read->stfb); - - if ((nv->dri_drawable != driDrawPriv) || - (nv->last_stamp != driDrawPriv->lastStamp)) { - nv->dri_drawable = driDrawPriv; - st_resize_framebuffer(draw->stfb, driDrawPriv->w, - driDrawPriv->h); - nv->last_stamp = driDrawPriv->lastStamp; - } - - if (driDrawPriv != driReadPriv) { - st_resize_framebuffer(read->stfb, driReadPriv->w, - driReadPriv->h); - } - - return GL_TRUE; -} - -GLboolean -nouveau_context_unbind(__DRIcontextPrivate *driContextPriv) -{ - struct nouveau_context *nv = driContextPriv->driverPrivate; - (void)nv; - - st_flush(nv->st, 0, NULL); - return GL_TRUE; -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h deleted file mode 100644 index 2779b092e6..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __NOUVEAU_CONTEXT_DRI_H__ -#define __NOUVEAU_CONTEXT_DRI_H__ - -#include <dri_util.h> -#include <xmlconfig.h> - -#include "nouveau/nouveau_winsys.h" - -#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args) - -struct nouveau_framebuffer { - struct st_framebuffer *stfb; -}; - -struct nouveau_context { - struct st_context *st; - - /* DRI stuff */ - __DRIscreenPrivate *dri_screen; - __DRIdrawablePrivate *dri_drawable; - unsigned int last_stamp; - driOptionCache dri_option_cache; - drm_context_t drm_context; - drmLock drm_lock; - int locked; -}; - -extern GLboolean nouveau_context_create(const __GLcontextModes *, - __DRIcontextPrivate *, void *); -extern void nouveau_context_destroy(__DRIcontextPrivate *); -extern GLboolean nouveau_context_bind(__DRIcontextPrivate *, - __DRIdrawablePrivate *draw, - __DRIdrawablePrivate *read); -extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *); - -extern void nouveau_contended_lock(struct nouveau_context *nv); -extern void LOCK_HARDWARE(struct nouveau_context *nv); -extern void UNLOCK_HARDWARE(struct nouveau_context *nv); - -#ifdef DEBUG -extern int __nouveau_debug; - -#define DEBUG_BO (1 << 0) - -#define DBG(flag, ...) do { \ - if (__nouveau_debug & (DEBUG_##flag)) \ - NOUVEAU_ERR(__VA_ARGS__); \ -} while(0) -#else -#define DBG(flag, ...) -#endif - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c deleted file mode 100644 index 92f5bd09c9..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************** - * - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include <pipe/p_thread.h> -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_drmif.h" - -pipe_static_mutex(lockMutex); - -/* Lock the hardware and validate our state. - */ -void -LOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - char __ret=0; - - assert(!nv->locked); - pipe_mutex_lock(lockMutex); - - DRM_CAS(nvdev->lock, nvdev->ctx, - (DRM_LOCK_HELD | nvdev->ctx), __ret); - - if (__ret) { - drmGetLock(nvdev->fd, nvdev->ctx, 0); - nouveau_contended_lock(nv); - } - nv->locked = 1; -} - -/* Unlock the hardware using the global current context - */ -void -UNLOCK_HARDWARE(struct nouveau_context *nv) -{ - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct nouveau_device *dev = nv_screen->device; - struct nouveau_device_priv *nvdev = nouveau_device(dev); - - assert(nv->locked); - nv->locked = 0; - - DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx); - - pipe_mutex_unlock(lockMutex); -} diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c deleted file mode 100644 index 4e9b76a909..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c +++ /dev/null @@ -1,330 +0,0 @@ -#include <utils.h> -#include <vblank.h> -#include <xmlpool.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_cb_fbo.h> -#include <state_tracker/drm_api.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" -#include "nouveau_dri.h" - -#include "nouveau_drm.h" -#include "nouveau_drmif.h" - -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 -#error nouveau_drm.h version does not match expected version -#endif - -/* Extension stuff, enabling of extensions handled by Gallium's GL state - * tracker. But, we still need to define the entry points we want. - */ -#define need_GL_ARB_fragment_program -#define need_GL_ARB_multisample -#define need_GL_ARB_occlusion_query -#define need_GL_ARB_point_parameters -#define need_GL_ARB_shader_objects -#define need_GL_ARB_texture_compression -#define need_GL_ARB_vertex_program -#define need_GL_ARB_vertex_shader -#define need_GL_ARB_vertex_buffer_object -#define need_GL_EXT_compiled_vertex_array -#define need_GL_EXT_fog_coord -#define need_GL_EXT_secondary_color -#define need_GL_EXT_framebuffer_object -#define need_GL_VERSION_2_0 -#define need_GL_VERSION_2_1 -#include "extension_helper.h" - -const struct dri_extension card_extensions[] = -{ - { "GL_ARB_multisample", GL_ARB_multisample_functions }, - { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions }, - { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions }, - { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, - { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, - { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, - { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, - { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, - { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions }, - { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, - { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, - { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions }, - { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, - { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, - { NULL, 0 } -}; - -PUBLIC const char __driConfigOptions[] = -DRI_CONF_BEGIN -DRI_CONF_END; -static const GLuint __driNConfigOptions = 0; - -extern const struct dri_extension common_extensions[]; -extern const struct dri_extension nv40_extensions[]; - -static GLboolean -nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv, - __DRIdrawablePrivate * driDrawPriv, - const __GLcontextModes *glVis, GLboolean pixmapBuffer) -{ - struct nouveau_framebuffer *nvfb; - enum pipe_format colour, depth, stencil; - - if (pixmapBuffer) - return GL_FALSE; - - nvfb = CALLOC_STRUCT(nouveau_framebuffer); - if (!nvfb) - return GL_FALSE; - - if (glVis->redBits == 5) - colour = PIPE_FORMAT_R5G6B5_UNORM; - else - colour = PIPE_FORMAT_A8R8G8B8_UNORM; - - if (glVis->depthBits == 16) - depth = PIPE_FORMAT_Z16_UNORM; - else if (glVis->depthBits == 24) - depth = PIPE_FORMAT_Z24S8_UNORM; - else - depth = PIPE_FORMAT_NONE; - - if (glVis->stencilBits == 8) - stencil = PIPE_FORMAT_Z24S8_UNORM; - else - stencil = PIPE_FORMAT_NONE; - - nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil, - driDrawPriv->w, driDrawPriv->h, - (void*)nvfb); - if (!nvfb->stfb) { - free(nvfb); - return GL_FALSE; - } - - driDrawPriv->driverPrivate = (void *)nvfb; - return GL_TRUE; -} - -static void -nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv) -{ - struct nouveau_framebuffer *nvfb; - - nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate; - st_unreference_framebuffer(nvfb->stfb); - free(nvfb); -} - -static __DRIconfig ** -nouveau_fill_in_modes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) -{ - __DRIconfig **configs; - unsigned depth_buffer_factor; - unsigned back_buffer_factor; - GLenum fb_format; - GLenum fb_type; - - static const GLenum back_buffer_modes[] = { - GLX_NONE, GLX_SWAP_UNDEFINED_OML, - }; - - uint8_t depth_bits_array[3]; - uint8_t stencil_bits_array[3]; - uint8_t msaa_samples_array[1]; - - depth_bits_array[0] = 0; - depth_bits_array[1] = depth_bits; - depth_bits_array[2] = depth_bits; - - /* Just like with the accumulation buffer, always provide some modes - * with a stencil buffer. It will be a sw fallback, but some apps won't - * care about that. - */ - stencil_bits_array[0] = 0; - stencil_bits_array[1] = 0; - if (depth_bits == 24) - stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; - stencil_bits_array[2] = (stencil_bits == 0) ? 8 : stencil_bits; - - msaa_samples_array[0] = 0; - - depth_buffer_factor = - ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1; - back_buffer_factor = (have_back_buffer) ? 3 : 1; - - if (pixel_bits == 16) { - fb_format = GL_RGB; - fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { - fb_format = GL_BGRA; - fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; - } - - configs = driCreateConfigs(fb_format, fb_type, - depth_bits_array, stencil_bits_array, - depth_buffer_factor, back_buffer_modes, - back_buffer_factor, msaa_samples_array, 1); - if (configs == NULL) { - fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", - __func__, __LINE__); - return NULL; - } - - return configs; -} - -static struct pipe_surface * -dri_surface_from_handle(struct pipe_screen *screen, - unsigned handle, - enum pipe_format format, - unsigned width, - unsigned height, - unsigned pitch) -{ - struct pipe_surface *surface = NULL; - struct pipe_texture *texture = NULL; - struct pipe_texture templat; - struct pipe_buffer *buf = NULL; - - buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle); - if (!buf) - return NULL; - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | - NOUVEAU_TEXTURE_USAGE_LINEAR; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth[0] = 1; - templat.format = format; - templat.width[0] = width; - templat.height[0] = height; - pf_get_block(templat.format, &templat.block); - - texture = screen->texture_blanket(screen, - &templat, - &pitch, - buf); - - /* we don't need the buffer from this point on */ - pipe_buffer_reference(&buf, NULL); - - if (!texture) - return NULL; - - surface = screen->get_tex_surface(screen, texture, 0, 0, 0, - PIPE_BUFFER_USAGE_GPU_READ | - PIPE_BUFFER_USAGE_GPU_WRITE); - - /* we don't need the texture from this point on */ - pipe_texture_reference(&texture, NULL); - return surface; -} - -static const __DRIconfig ** -nouveau_screen_create(__DRIscreenPrivate *psp) -{ - struct nouveau_dri *nv_dri = psp->pDevPriv; - struct nouveau_screen *nv_screen; - static const __DRIversion ddx_expected = - { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; - static const __DRIversion dri_expected = { 4, 0, 0 }; - static const __DRIversion drm_expected = - { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL }; - - if (!driCheckDriDdxDrmVersions2("nouveau", - &psp->dri_version, &dri_expected, - &psp->ddx_version, &ddx_expected, - &psp->drm_version, &drm_expected)) { - return NULL; - } - - if (drm_expected.patch != psp->drm_version.patch) { - fprintf(stderr, "Incompatible DRM patch level.\n" - "Expected: %d\n" "Current : %d\n", - drm_expected.patch, psp->drm_version.patch); - return NULL; - } - - driInitExtensions(NULL, card_extensions, GL_FALSE); - - if (psp->devPrivSize != sizeof(struct nouveau_dri)) { - NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n"); - return NULL; - } - - nv_screen = CALLOC_STRUCT(nouveau_screen); - if (!nv_screen) - return NULL; - - nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0); - - nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, NULL); - if (!nv_screen->pscreen) { - FREE(nv_screen); - return NULL; - } - nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer; - - { - enum pipe_format format; - - if (nv_dri->bpp == 16) - format = PIPE_FORMAT_R5G6B5_UNORM; - else - format = PIPE_FORMAT_A8R8G8B8_UNORM; - - nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen, - nv_dri->front_offset, - format, - nv_dri->width, - nv_dri->height, - nv_dri->front_pitch * - nv_dri->bpp / 8); - } - - driParseOptionInfo(&nv_screen->option_cache, - __driConfigOptions, __driNConfigOptions); - - nv_screen->driScrnPriv = psp; - psp->private = (void *)nv_screen; - - return (const __DRIconfig **) - nouveau_fill_in_modes(psp, nv_dri->bpp, - (nv_dri->bpp == 16) ? 16 : 24, - (nv_dri->bpp == 16) ? 0 : 8, 1); -} - -static void -nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv) -{ - struct nouveau_screen *nv_screen = driScrnPriv->private; - - driScrnPriv->private = NULL; - FREE(nv_screen); -} - -const struct __DriverAPIRec -driDriverAPI = { - .InitScreen = nouveau_screen_create, - .DestroyScreen = nouveau_screen_destroy, - .CreateContext = nouveau_context_create, - .DestroyContext = nouveau_context_destroy, - .CreateBuffer = nouveau_create_buffer, - .DestroyBuffer = nouveau_destroy_buffer, - .SwapBuffers = nouveau_swap_buffers, - .MakeCurrent = nouveau_context_bind, - .UnbindContext = nouveau_context_unbind, - .CopySubBuffer = nouveau_copy_sub_buffer, - - .InitScreen2 = NULL, /* one day, I promise! */ -}; - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h deleted file mode 100644 index ac078f3c63..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __NOUVEAU_SCREEN_DRI_H__ -#define __NOUVEAU_SCREEN_DRI_H__ - -#include "xmlconfig.h" - -struct nouveau_screen { - __DRIscreenPrivate *driScrnPriv; - driOptionCache option_cache; - - struct nouveau_device *device; - - struct pipe_screen *pscreen; - struct pipe_surface *fb; -}; - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c deleted file mode 100644 index 9c841a0b2d..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c +++ /dev/null @@ -1,115 +0,0 @@ -#include <main/glheader.h> -#include <glapi/glthread.h> -#include <GL/internal/glcore.h> - -#include <pipe/p_context.h> -#include <state_tracker/st_public.h> -#include <state_tracker/st_context.h> -#include <state_tracker/st_cb_fbo.h> - -#include "nouveau_context.h" -#include "nouveau_screen.h" -#include "nouveau_swapbuffers.h" - -#include "nouveau_pushbuf.h" - -void -nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf, - const drm_clip_rect_t *rect) -{ - struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate; - struct nouveau_screen *nv_screen = nv->dri_screen->private; - struct pipe_context *pipe = nv->st->pipe; - drm_clip_rect_t *pbox; - int nbox, i; - - LOCK_HARDWARE(nv); - if (!dPriv->numClipRects) { - UNLOCK_HARDWARE(nv); - return; - } - pbox = dPriv->pClipRects; - nbox = dPriv->numClipRects; - - for (i = 0; i < nbox; i++, pbox++) { - int sx, sy, dx, dy, w, h; - - sx = pbox->x1 - dPriv->x; - sy = pbox->y1 - dPriv->y; - dx = pbox->x1; - dy = pbox->y1; - w = pbox->x2 - pbox->x1; - h = pbox->y2 - pbox->y1; - - pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf, - sx, sy, w, h); - } - - pipe->flush(pipe, 0, NULL); - UNLOCK_HARDWARE(nv); - - if (nv->last_stamp != dPriv->lastStamp) { - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h); - nv->last_stamp = dPriv->lastStamp; - } -} - -void -nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h) -{ - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - struct pipe_surface *surf; - - st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - drm_clip_rect_t rect; - rect.x1 = x; - rect.y1 = y; - rect.x2 = x + w; - rect.y2 = y + h; - - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, &rect); - } -} - -void -nouveau_swap_buffers(__DRIdrawablePrivate *dPriv) -{ - struct nouveau_framebuffer *nvfb = dPriv->driverPrivate; - struct pipe_surface *surf; - - st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - st_notify_swapbuffers(nvfb->stfb); - nouveau_copy_buffer(dPriv, surf, NULL); - } -} - -void -nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps, - void *context_private) -{ - struct nouveau_context *nv = context_private; - __DRIdrawablePrivate *dPriv = nv->dri_drawable; - - nouveau_copy_buffer(dPriv, ps, NULL); -} - -void -nouveau_contended_lock(struct nouveau_context *nv) -{ - struct nouveau_context *nv_sub = (struct nouveau_context*)nv; - __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable; - __DRIscreenPrivate *sPriv = nv_sub->dri_screen; - - /* If the window moved, may need to set a new cliprect now. - * - * NOTE: This releases and regains the hw lock, so all state - * checking must be done *after* this call: - */ - if (dPriv) - DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); -} - diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h deleted file mode 100644 index 4ca9cc2283..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NOUVEAU_SWAPBUFFERS_H__ -#define __NOUVEAU_SWAPBUFFERS_H__ - -void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *, - const drm_clip_rect_t *); -void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h); -void nouveau_swap_buffers(__DRIdrawablePrivate *); -void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *, - void *context_private); - -#endif diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile deleted file mode 100644 index 377a80d518..0000000000 --- a/src/gallium/winsys/drm/nouveau/dri2/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -TOP = ../../../../../.. -include $(TOP)/configs/current - -LIBNAME = nouveau_dri2.so - -PIPE_DRIVERS = \ - $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \ - $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \ - $(TOP)/src/gallium/drivers/nv04/libnv04.a \ - $(TOP)/src/gallium/drivers/nv10/libnv10.a \ - $(TOP)/src/gallium/drivers/nv20/libnv20.a \ - $(TOP)/src/gallium/drivers/nv30/libnv30.a \ - $(TOP)/src/gallium/drivers/nv40/libnv40.a \ - $(TOP)/src/gallium/drivers/nv50/libnv50.a - -DRIVER_SOURCES = - -C_SOURCES = \ - $(COMMON_GALLIUM_SOURCES) \ - $(DRIVER_SOURCES) - -include ../../Makefile.template - -DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs) - -symlinks: diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h index 1207c2d609..1207c2d609 100644 --- a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c index a558fda140..b355a1391d 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c @@ -7,9 +7,68 @@ #include "nouveau_channel.h" #include "nouveau_bo.h" +static struct pipe_surface * +dri_surface_from_handle(struct pipe_screen *screen, + unsigned handle, + enum pipe_format format, + unsigned width, + unsigned height, + unsigned pitch) +{ + struct pipe_surface *surface = NULL; + struct pipe_texture *texture = NULL; + struct pipe_texture templat; + struct pipe_buffer *buf = NULL; + + buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle); + if (!buf) + return NULL; + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY | + NOUVEAU_TEXTURE_USAGE_LINEAR; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = format; + templat.width[0] = width; + templat.height[0] = height; + pf_get_block(templat.format, &templat.block); + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buf); + + /* we don't need the buffer from this point on */ + pipe_buffer_reference(&buf, NULL); + + if (!texture) + return NULL; + + surface = screen->get_tex_surface(screen, texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + /* we don't need the texture from this point on */ + pipe_texture_reference(&texture, NULL); + return surface; +} + +static struct pipe_surface * +nouveau_dri1_front_surface(struct pipe_context *pipe) +{ + return nouveau_screen(pipe->screen)->front; +} + +static struct dri1_api nouveau_dri1_api = { + nouveau_dri1_front_surface, +}; + static struct pipe_screen * nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) { + struct dri1_create_screen_arg *dri1 = (void *)arg; struct pipe_winsys *ws; struct nouveau_winsys *nvws; struct nouveau_device *dev = NULL; @@ -67,6 +126,33 @@ nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg) return NULL; } + if (arg->mode == DRM_CREATE_DRI1) { + struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws); + struct nouveau_dri *nvdri = dri1->ddx_info; + enum pipe_format format; + + if (nvdri->bpp == 16) + format = PIPE_FORMAT_R5G6B5_UNORM; + else + format = PIPE_FORMAT_A8R8G8B8_UNORM; + + nvpws->front = dri_surface_from_handle(nvpws->pscreen, + nvdri->front_offset, + format, + nvdri->width, + nvdri->height, + nvdri->front_pitch * + (nvdri->bpp / 8)); + if (!nvpws->front) { + debug_printf("%s: error referencing front buffer\n", + __func__); + ws->destroy(ws); + return NULL; + } + + dri1->api = &nouveau_dri1_api; + } + return nouveau_pipe_winsys(ws)->pscreen; } diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h index 2782c83c0e..cc237bfc13 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h @@ -1,5 +1,7 @@ #ifndef __NOUVEAU_DRM_API_H__ #define __NOUVEAU_DRM_API_H__ #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" +#include "nouveau_dri.h" #endif diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h index 10e1e269e8..ec10f1e00c 100644 --- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h +++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h @@ -29,6 +29,8 @@ struct nouveau_pipe_winsys { unsigned nr_pctx; struct pipe_context **pctx; + + struct pipe_surface *front; }; static INLINE struct nouveau_pipe_winsys * diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c index da233203d7..56b0d00842 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c @@ -35,33 +35,38 @@ static void radeon_r300_add_buffer(struct r300_winsys* winsys, /* Check to see if this BO is already in line for validation; * find a slot for it otherwise. */ - for (i = 0; i < RADEON_MAX_BOS; i++) { + assert(priv->bo_count <= RADEON_MAX_BOS); + for (i = 0; i < priv->bo_count; i++) { if (sc[i].bo == bo) { - return; - } else if (sc[i].bo == NULL) { - sc[i].bo = bo; - sc[i].read_domains = rd; - sc[i].write_domain = wd; - priv->bo_count = i + 1; + sc[i].read_domains |= rd; + sc[i].write_domain |= wd; return; } } - assert(FALSE && "Oh God too many BOs!"); + sc[priv->bo_count].bo = bo; + sc[priv->bo_count].read_domains = rd; + sc[priv->bo_count].write_domain = wd; + priv->bo_count++; } static boolean radeon_r300_validate(struct r300_winsys* winsys) { - int retval; + int retval, i; struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; struct radeon_cs_space_check* sc = priv->sc; + debug_printf("Validation count: %d\n", priv->bo_count); + for (i = 0; i < priv->bo_count; i++) { + debug_printf("BO %d: %p rd: %d wd: %d\n", i, sc[i].bo, sc[i].read_domains, sc[i].write_domain); + } retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count); if (retval == RADEON_CS_SPACE_OP_TO_BIG) { /* We might as well HCF, since this is not going to fit in the card, * period. */ + /* XXX just drop it on the floor instead */ exit(1); } else if (retval == RADEON_CS_SPACE_FLUSH) { /* We must flush before more rendering can commence. */ @@ -128,57 +133,81 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys) { struct radeon_winsys_priv* priv = (struct radeon_winsys_priv*)winsys->radeon_winsys; - int retval = 0; + struct radeon_cs_space_check* sc = priv->sc; + int retval = 1; + /* Emit the CS. */ retval = radeon_cs_emit(priv->cs); if (retval) { debug_printf("radeon: Bad CS, dumping...\n"); radeon_cs_print(priv->cs, stderr); } radeon_cs_erase(priv->cs); + + /* Clean out BOs. */ + memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS); + priv->bo_count = 0; } /* Helper function to do the ioctls needed for setup and init. */ static void do_ioctls(struct r300_winsys* winsys, int fd) { - struct drm_radeon_gem_info info; - drm_radeon_getparam_t gp; - int target; + struct drm_radeon_gem_info gem_info = {0}; + drm_radeon_getparam_t gp = {0}; + struct drm_radeon_info info = {0}; + int target = 0; int retval; + info.value = ⌖ gp.value = ⌖ /* First, get the number of pixel pipes */ - gp.param = RADEON_PARAM_NUM_GB_PIPES; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + info.request = RADEON_INFO_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { - fprintf(stderr, "%s: Failed to get GB pipe count, error number %d\n", + fprintf(stderr, "%s: New ioctl for GB pipe count failed " + "(error number %d), trying classic ioctl...\n", __FUNCTION__, retval); - exit(1); + gp.param = RADEON_PARAM_NUM_GB_PIPES; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, + sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get GB pipe count, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } } winsys->gb_pipes = target; /* Then, get PCI ID */ - gp.param = RADEON_PARAM_DEVICE_ID; - retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); + info.request = RADEON_INFO_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info)); if (retval) { - fprintf(stderr, "%s: Failed to get PCI ID, error number %d\n", + fprintf(stderr, "%s: New ioctl for PCI ID failed " + "(error number %d), trying classic ioctl...\n", __FUNCTION__, retval); - exit(1); + gp.param = RADEON_PARAM_DEVICE_ID; + retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, + sizeof(gp)); + if (retval) { + fprintf(stderr, "%s: Failed to get PCI ID, " + "error number %d\n", __FUNCTION__, retval); + exit(1); + } } winsys->pci_id = target; /* Finally, retrieve MM info */ retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO, - &info, sizeof(info)); + &gem_info, sizeof(gem_info)); if (retval) { fprintf(stderr, "%s: Failed to get MM info, error number %d\n", __FUNCTION__, retval); exit(1); } - winsys->gart_size = info.gart_size; + winsys->gart_size = gem_info.gart_size; /* XXX */ - winsys->vram_size = info.vram_visible; + winsys->vram_size = gem_info.vram_visible; } struct r300_winsys* diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h index 5c373cd084..19c7ed2626 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h +++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h @@ -31,5 +31,21 @@ #include "radeon_buffer.h" +/* protect us from bonghits */ +#ifndef RADEON_INFO_NUM_GB_PIPES +#define RADEON_INFO_NUM_GB_PIPES 0 +#endif +#ifndef RADEON_INFO_DEVICE_ID +#define RADEON_INFO_DEVICE_ID 0 +#endif +#ifndef DRM_RADEON_INFO +#define DRM_RADEON_INFO 0x1 +struct drm_radeon_info { + uint32_t request; + uint32_t pad; + uint64_t value; +}; +#endif + struct r300_winsys* radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys); diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c index b52f427e4a..c10e3c00ff 100644 --- a/src/gallium/winsys/egl_xlib/egl_xlib.c +++ b/src/gallium/winsys/egl_xlib/egl_xlib.c @@ -588,7 +588,9 @@ find_supported_apis(void) EGLint mask = 0; void *handle; - handle = dlopen(NULL, 0); + handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); + if(!handle) + return mask; if (dlsym(handle, "st_api_OpenGL_ES1")) mask |= EGL_OPENGL_ES_BIT; |