diff options
author | Christian König <[email protected]> | 2010-11-11 21:07:42 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2010-11-11 21:07:42 +0100 |
commit | 195bbe8ce218533569dde1368d04da0fd229913d (patch) | |
tree | 29d3db04673f59dcfd6663c524a5c1343d5cbee6 /src/gallium/drivers | |
parent | 99b57bc20e839043ec6160502814085a0976fccc (diff) | |
parent | d67df5dd9db1cede92f1b177c890f83809bb4582 (diff) |
Merge remote branch 'origin/master' into pipe-video
Diffstat (limited to 'src/gallium/drivers')
40 files changed, 421 insertions, 267 deletions
diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript index f8e9b1b4911..9347431f4e5 100644 --- a/src/gallium/drivers/failover/SConscript +++ b/src/gallium/drivers/failover/SConscript @@ -10,4 +10,6 @@ failover = env.ConvenienceLibrary( 'fo_context.c', ]) +env.Alias('failover', failover) + Export('failover') diff --git a/src/gallium/drivers/galahad/SConscript b/src/gallium/drivers/galahad/SConscript index b398a3f0615..3f39f99e517 100644 --- a/src/gallium/drivers/galahad/SConscript +++ b/src/gallium/drivers/galahad/SConscript @@ -3,11 +3,13 @@ Import('*') env = env.Clone() galahad = env.ConvenienceLibrary( - target = 'identity', + target = 'galahad', source = [ 'glhd_context.c', 'glhd_objects.c', 'glhd_screen.c', ]) +env.Alias('galahad', galahad) + Export('galahad') diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript index d4bf6fef134..8f5deed64a9 100644 --- a/src/gallium/drivers/i915/SConscript +++ b/src/gallium/drivers/i915/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i915g' - Return() - i915 = env.ConvenienceLibrary( target = 'i915', source = [ @@ -34,4 +30,6 @@ i915 = env.ConvenienceLibrary( 'i915_resource_texture.c', ]) +env.Alias('i915', i915) + Export('i915') diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript index 119f914a16d..019af682f68 100644 --- a/src/gallium/drivers/i965/SConscript +++ b/src/gallium/drivers/i965/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i965g' - Return(); - i965 = env.ConvenienceLibrary( target = 'i965', source = [ diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index ec30d4d7084..e9374cc6efa 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -1,53 +1,6 @@ LLVMPIPE -- a fork of softpipe that employs LLVM for code generation. -Status -====== - -Done so far is: - - - the whole fragment pipeline is code generated in a single function - - - input interpolation - - - depth testing - - - texture sampling - - 1D/2D/3D/cube maps supported - - all texture wrap modes supported - - all texture filtering modes supported - - perhaps not all texture formats yet supported - - - fragment shader TGSI translation - - same level of support as the TGSI SSE2 exec machine, with the exception - we don't fallback to TGSI interpretation when an unsupported opcode is - found, but just ignore it - - done in SoA layout - - input interpolation also code generated - - - alpha testing - - - blend (including logic ops) - - both in SoA and AoS layouts, but only the former used for now - - - code is generic - - intermediates can be vectors of floats, ubytes, fixed point, etc, and of - any width and length - - not all operations are implemented for these types yet though - -Most mesa/progs/demos/* work. - -To do (probably by this order): - - - code generate stipple and stencil testing - - - translate TGSI control flow instructions, and all other remaining opcodes - - - integrate with the draw module for VS code generation - - - code generate the triangle setup and rasterization - - Requirements ============ @@ -98,7 +51,7 @@ Building To build everything on Linux invoke scons as: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false + scons build=debug libgl-xlib Alternatively, you can build it with GNU make, if you prefer, by invoking it as @@ -108,19 +61,16 @@ but the rest of these instructions assume that scons is used. For windows is everything the except except the winsys: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=gdi dri=false + scons build=debug libgl-gdi Using ===== -On Linux, building will create a drop-in alternative for libGL.so. To use it -set the environment variables: - - export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/lib:$LD_LIBRARY_PATH +On Linux, building will create a drop-in alternative for libGL.so into -or + build/foo/gallium/targets/libgl-xlib/libGL.so - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib:$LD_LIBRARY_PATH +To use it set the LD_LIBRARY_PATH environment variable accordingly. For performance evaluation pass debug=no to scons, and use the corresponding lib directory without the "-debug" suffix. @@ -136,7 +86,7 @@ Profiling To profile llvmpipe you should pass the options - scons debug=no profile=yes <same-as-before> + scons build=profile <same-as-before> This will ensure that frame pointers are used both in C and JIT functions, and that no tail call optimizations are done by gcc. @@ -200,5 +150,4 @@ Development Notes interfaces very closely, and appear to be complete enough for code generation. See http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html - for a stand-alone example. - See the llvm-c/Core.h file for reference. + for a stand-alone example. See the llvm-c/Core.h file for reference. diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 49950153a4f..26b258b9569 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -9,8 +9,6 @@ if not env['llvm']: env = env.Clone() -env.Tool('udis86') - env.Append(CPPPATH = ['.']) env.CodeGenerate( @@ -78,6 +76,8 @@ llvmpipe = env.ConvenienceLibrary( lp_tile_soa_os, ]) +env.Alias('llvmpipe', llvmpipe) + if env['platform'] != 'embedded': env = env.Clone() @@ -92,7 +92,7 @@ if env['platform'] != 'embedded': 'sincos', ] - if not msvc: + if not env['msvc']: tests.append('round') for test in tests: diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d358a983943..decf3bd4499 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -485,8 +485,11 @@ static void lp_rast_end_query(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { - task->query->count[task->thread_index] += task->vis_counter; - task->query = NULL; + assert(task->query); + if (task->query) { + task->query->count[task->thread_index] += task->vis_counter; + task->query = NULL; + } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index 827413bb33e..29c231714e1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -569,7 +569,10 @@ try_setup_line( struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions: + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); line = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -680,24 +683,26 @@ try_setup_line( struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 8) { + const struct u_rect *scissor = &setup->scissor; + plane[4].dcdx = -1; plane[4].dcdy = 0; - plane[4].c = 1-bbox.x0; + plane[4].c = 1-scissor->x0; plane[4].eo = 1; plane[5].dcdx = 1; plane[5].dcdy = 0; - plane[5].c = bbox.x1+1; + plane[5].c = scissor->x1+1; plane[5].eo = 0; plane[6].dcdx = 0; plane[6].dcdy = 1; - plane[6].c = 1-bbox.y0; + plane[6].c = 1-scissor->y0; plane[6].eo = 1; plane[7].dcdx = 0; plane[7].dcdy = -1; - plane[7].c = bbox.y1+1; + plane[7].c = scissor->y1+1; plane[7].eo = 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 4ab0b72a574..bfb6bf277bd 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -295,7 +295,12 @@ do_triangle_ccw(struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions, but need to keep hold of + * information about when the triangle extends past screen + * boundaries. See trimmed_box in lp_setup_bin_triangle(). + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); tri = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -501,24 +506,26 @@ do_triangle_ccw(struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 7) { + const struct u_rect *scissor = &setup->scissor; + plane[3].dcdx = -1; plane[3].dcdy = 0; - plane[3].c = 1-bbox.x0; + plane[3].c = 1-scissor->x0; plane[3].eo = 1; plane[4].dcdx = 1; plane[4].dcdy = 0; - plane[4].c = bbox.x1+1; + plane[4].c = scissor->x1+1; plane[4].eo = 0; plane[5].dcdx = 0; plane[5].dcdy = 1; - plane[5].c = 1-bbox.y0; + plane[5].c = 1-scissor->y0; plane[5].eo = 1; plane[6].dcdx = 0; plane[6].dcdy = -1; - plane[6].c = bbox.y1+1; + plane[6].c = scissor->y1+1; plane[6].eo = 0; } @@ -559,6 +566,7 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int nr_planes ) { struct lp_scene *scene = setup->scene; + struct u_rect trimmed_box = *bbox; int i; /* What is the largest power-of-two boundary this triangle crosses: @@ -572,6 +580,13 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int sz = floor_pot((bbox->x1 - (bbox->x0 & ~3)) | (bbox->y1 - (bbox->y0 & ~3))); + /* Now apply scissor, etc to the bounding box. Could do this + * earlier, but it confuses the logic for tri-16 and would force + * the rasterizer to also respect scissor, etc, just for the rare + * cases where a small triangle extends beyond the scissor. + */ + u_rect_find_intersection(&setup->draw_region, &trimmed_box); + /* Determine which tile(s) intersect the triangle's bounding box */ if (dx < TILE_SIZE) @@ -626,15 +641,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, struct lp_rast_plane *plane = GET_PLANES(tri); int c[MAX_PLANES]; int ei[MAX_PLANES]; + int eo[MAX_PLANES]; int xstep[MAX_PLANES]; int ystep[MAX_PLANES]; int x, y; - int ix0 = bbox->x0 / TILE_SIZE; - int iy0 = bbox->y0 / TILE_SIZE; - int ix1 = bbox->x1 / TILE_SIZE; - int iy1 = bbox->y1 / TILE_SIZE; + int ix0 = trimmed_box.x0 / TILE_SIZE; + int iy0 = trimmed_box.y0 / TILE_SIZE; + int ix1 = trimmed_box.x1 / TILE_SIZE; + int iy1 = trimmed_box.y1 / TILE_SIZE; for (i = 0; i < nr_planes; i++) { c[i] = (plane[i].c + @@ -799,6 +815,16 @@ static void triangle_both( struct lp_setup_context *setup, { float area = calc_area(v0, v1, v2); + if (0) { + assert(!util_is_inf_or_nan(v0[0][0])); + assert(!util_is_inf_or_nan(v0[0][1])); + assert(!util_is_inf_or_nan(v1[0][0])); + assert(!util_is_inf_or_nan(v1[0][1])); + assert(!util_is_inf_or_nan(v2[0][0])); + assert(!util_is_inf_or_nan(v2[0][1])); + assert(!util_is_inf_or_nan(area)); + } + if (area > 0.0f) retry_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface ); else if (area < 0.0f) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9fbedac165f..48971510f21 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -761,11 +761,6 @@ generate_fragment(struct llvmpipe_screen *screen, } } -#ifdef PIPE_ARCH_X86 - /* Avoid corrupting the FPU stack on 32bit OSes. */ - lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); -#endif - LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -1067,11 +1062,11 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs) draw_flush(llvmpipe->draw); + llvmpipe->fs = (struct lp_fragment_shader *) fs; + draw_bind_fragment_shader(llvmpipe->draw, (llvmpipe->fs ? llvmpipe->fs->draw_data : NULL)); - llvmpipe->fs = fs; - llvmpipe->dirty |= LP_NEW_FS; } diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 6c41e8f4561..306aa81d985 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -39,6 +39,9 @@ nv50_transfer_constbuf(struct nv50_context *nv50, uint32_t *map; unsigned count, start; + if (buf == NULL) + return; + map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer); if (!map) return; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 875b3a96ca6..f3ed4ad5bdd 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -78,6 +78,10 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; // TODO: implement depth clamp + case PIPE_CAP_PRIMITIVE_RESTART: + return 0; // TODO: implement primitive restart + case PIPE_CAP_SHADER_STENCIL_EXPORT: + return 0; default: NOUVEAU_ERR("Warning: unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index bf023daaa56..b49db937994 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -39,5 +39,7 @@ r300 = env.ConvenienceLibrary( 'r300_transfer.c', ] + r300compiler) + r300compiler +env.Alias('r300', r300) + Export('r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 91a374a5838..0ac4e4c6f12 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -176,12 +176,12 @@ static void r300_clear(struct pipe_context* pipe, fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL; uint32_t width = fb->width; uint32_t height = fb->height; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; /* Enable fast Z clear. * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ - if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && has_hyperz) { + if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) { hyperz_dcv = hyperz->zb_depthclearvalue = r300_depth_clear_value(fb->zsbuf->format, depth, stencil); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 624dadd07d7..fb099e2a7d0 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -184,7 +184,7 @@ static void r300_setup_atoms(struct r300_context* r300) boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0); - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. @@ -240,7 +240,7 @@ static void r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); - if (has_hyperz) { + if (can_hyperz) { /* HiZ Clear */ if (has_hiz_ram) R300_INIT_ATOM(hiz_clear, 0); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3a1085d2dc5..c187f115da4 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -358,7 +358,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); CS_LOCALS(r300); BEGIN_CS(size); @@ -411,7 +411,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); - if (has_hyperz) { + if (can_hyperz) { uint32_t surf_pitch; struct r300_texture *tex; int level = surf->base.level; diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index eb5b0c36f8f..79f7f8abe9b 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -44,10 +44,10 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_SC_HYPERZ_MIN; - if (func >= 4 && func <= 7) + if (func >= R300_ZS_GEQUAL && func <= R300_ZS_ALWAYS) ret = R300_SC_HYPERZ_MAX; return ret; } @@ -55,23 +55,26 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) static bool r300_zfunc_same_direction(int func1, int func2) { /* func1 is less/lessthan */ - if (func1 == 1 || func1 == 2) - if (func2 == 3 || func2 == 4 || func2 == 5) + if ((func1 == R300_ZS_LESS || func1 == R300_ZS_LEQUAL) && + (func2 == R300_ZS_EQUAL || func2 == R300_ZS_GEQUAL || + func2 == R300_ZS_GREATER)) return FALSE; - if (func2 == 1 || func2 == 2) - if (func1 == 4 || func1 == 5) + /* func1 is greater/greaterthan */ + if ((func1 == R300_ZS_GEQUAL || func1 == R300_ZS_GREATER) && + (func2 == R300_ZS_LESS || func2 == R300_ZS_LEQUAL)) return FALSE; + return TRUE; } - + static int r300_get_hiz_min(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_HIZ_MIN; - if (func == 1 || func == 2) + if (func == R300_ZS_LESS || func == R300_ZS_LEQUAL) ret = R300_HIZ_MAX; return ret; } @@ -112,13 +115,16 @@ static boolean r300_can_hiz(struct r300_context *r300) } /* depth comparison function - if just cleared save and return okay */ if (z->current_func == -1) { - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; if (func != 0 && func != 7) - z->current_func = dsa_state->z_stencil_control & 0x7; + z->current_func = dsa_state->z_stencil_control & R300_ZS_MASK; } else { /* simple don't change */ - if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) { - DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control); + if (!r300_zfunc_same_direction(z->current_func, + (dsa_state->z_stencil_control & R300_ZS_MASK))) { + DBG(r300, DBG_HYPERZ, + "z func changed direction - disabling hyper-z %d -> %d\n", + z->current_func, dsa_state->z_stencil_control); return FALSE; } } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index d445df408dd..1d59e38aac5 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -44,31 +44,31 @@ static const char* r300_get_vendor(struct pipe_screen* pscreen) } static const char* chip_families[] = { - "R300", - "R350", - "R360", - "RV350", - "RV370", - "RV380", - "R420", - "R423", - "R430", - "R480", - "R481", - "RV410", - "RS400", - "RC410", - "RS480", - "RS482", - "RS600", - "RS690", - "RS740", - "RV515", - "R520", - "RV530", - "R580", - "RV560", - "RV570" + "ATI R300", + "ATI R350", + "ATI R360", + "ATI RV350", + "ATI RV370", + "ATI RV380", + "ATI R420", + "ATI R423", + "ATI R430", + "ATI R480", + "ATI R481", + "ATI RV410", + "ATI RS400", + "ATI RC410", + "ATI RS480", + "ATI RS482", + "ATI RS600", + "ATI RS690", + "ATI RS740", + "ATI RV515", + "ATI R520", + "ATI RV530", + "ATI R580", + "ATI RV560", + "ATI RV570" }; static const char* r300_get_name(struct pipe_screen* pscreen) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f2479a994c8..bd08bf2d3fd 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -684,7 +684,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); /* What is marked as dirty depends on the enum r300_fb_state_change. */ r300->gpu_flush.dirty = TRUE; @@ -703,7 +703,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, r300->fb_state.size += 10; else if (state->zsbuf) { r300->fb_state.size += 10; - if (has_hyperz) + if (can_hyperz) r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4; } @@ -717,7 +717,7 @@ static void struct r300_context* r300 = r300_context(pipe); struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct pipe_framebuffer_state *old_state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; int blocksize; @@ -764,7 +764,7 @@ static void zbuffer_bpp = 24; break; } - if (has_hyperz) { + if (can_hyperz) { struct r300_surface *zs_surf = r300_surface(state->zsbuf); struct r300_texture *tex; int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44; @@ -1789,7 +1789,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, { struct r300_context* r300 = r300_context(pipe); struct r300_constant_buffer *cbuf; - uint32_t *mapped = r300_buffer(buf)->user_buffer; + uint32_t *mapped; switch (shader) { case PIPE_SHADER_VERTEX: diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index bf0ad8571ba..3fc1fa94c27 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -25,10 +25,14 @@ r600 = env.ConvenienceLibrary( 'r600_resource.c', 'r600_shader.c', 'r600_state.c', + 'r600_state_common.c', 'r600_texture.c', + 'r600_translate.c', 'r700_asm.c', 'evergreen_state.c', 'eg_asm.c', ]) +env.Alias('r600', r600) + Export('r600') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index be81c28b43f..59641976403 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -473,7 +473,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d\n", format); + //R600_ERR("unsupported color format %d\n", format); return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 72223485067..4725b5e75e2 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -281,14 +281,21 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, tmp = (unsigned)(state->point_size * 8.0); r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, 0x00000008, 0xFFFFFFFF, NULL); + + tmp = (unsigned)state->line_width * 8; + r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C18_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0x0, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, 0x00000005, 0xFFFFFFFF, NULL); + + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL); return rstate; } @@ -826,6 +833,13 @@ static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index 8e96f9355e6..a337916c098 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1636,6 +1636,9 @@ #define R_028980_ALU_CONST_CACHE_VS_0 0x00028980 #define R_028A04_PA_SU_POINT_MINMAX 0x00028A04 #define R_028A08_PA_SU_LINE_CNTL 0x00028A08 +#define S_028A08_WIDTH(x) (((x) & 0xFFFF) << 0) +#define G_028A08_WIDTH(x) (((x) >> 0) & 0xFFFF) +#define C_028A08_WIDTH 0xFFFF0000 #define R_028A10_VGT_OUTPUT_PATH_CNTL 0x00028A10 #define R_028A14_VGT_HOS_CNTL 0x00028A14 #define R_028A18_VGT_HOS_MAX_TESS_LEVEL 0x00028A18 @@ -1687,6 +1690,9 @@ #define R_028C00_PA_SC_LINE_CNTL 0x00028C00 #define R_028C04_PA_SC_AA_CONFIG 0x00028C04 #define R_028C08_PA_SU_VTX_CNTL 0x00028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x00028C0C #define R_028C10_PA_CL_GB_VERT_DISC_ADJ 0x00028C10 #define R_028C14_PA_CL_GB_HORZ_CLIP_ADJ 0x00028C14 diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 62d983269f5..17858b2d381 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -43,6 +43,7 @@ typedef uint16_t u16; typedef uint8_t u8; struct radeon; +struct winsys_handle; enum radeon_family { CHIP_UNKNOWN, @@ -112,13 +113,16 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); /* r600_bo.c */ struct r600_bo; struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, unsigned usage); + unsigned size, unsigned alignment, + unsigned binding, unsigned usage); struct r600_bo *r600_bo_handle(struct radeon *radeon, unsigned handle, unsigned *array_mode); void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo); void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, struct r600_bo *src); +boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo, + unsigned stride, struct winsys_handle *whandle); static INLINE unsigned r600_bo_offset(struct r600_bo *bo) { return 0; diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 455aa2e81f6..ed97b6e69a3 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -38,32 +38,6 @@ extern struct u_resource_vtbl r600_buffer_vtbl; -u32 r600_domain_from_usage(unsigned usage) -{ - u32 domain = RADEON_GEM_DOMAIN_GTT; - - if (usage & PIPE_BIND_RENDER_TARGET) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_DEPTH_STENCIL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_SAMPLER_VIEW) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - /* also need BIND_BLIT_SOURCE/DESTINATION ? */ - if (usage & PIPE_BIND_VERTEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_INDEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_CONSTANT_BUFFER) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - - return domain; -} struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) @@ -85,8 +59,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, rbuffer->r.base.b.screen = screen; rbuffer->r.base.vtbl = &r600_buffer_vtbl; rbuffer->r.size = rbuffer->r.base.b.width0; - rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind); - bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind); + bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); if (bo == NULL) { FREE(rbuffer); return NULL; @@ -156,8 +129,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL); rbuffer->num_ranges = 0; rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys, - rbuffer->r.base.b.width0, 0, - rbuffer->r.base.b.bind); + rbuffer->r.base.b.width0, 0, + rbuffer->r.base.b.bind, + rbuffer->r.base.b.usage); break; } } diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 87ec8cd2e83..8a62d646d3a 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -78,13 +78,16 @@ static void r600_destroy_context(struct pipe_context *context) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)context; + rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); + r600_context_fini(&rctx->ctx); + + util_blitter_destroy(rctx->blitter); + for (int i = 0; i < R600_PIPE_NSTATES; i++) { free(rctx->states[i]); } - util_blitter_destroy(rctx->blitter); - u_upload_destroy(rctx->upload_vb); u_upload_destroy(rctx->upload_ib); @@ -219,24 +222,24 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen) static const char *r600_get_family_name(enum radeon_family family) { switch(family) { - case CHIP_R600: return "R600"; - case CHIP_RV610: return "RV610"; - case CHIP_RV630: return "RV630"; - case CHIP_RV670: return "RV670"; - case CHIP_RV620: return "RV620"; - case CHIP_RV635: return "RV635"; - case CHIP_RS780: return "RS780"; - case CHIP_RS880: return "RS880"; - case CHIP_RV770: return "RV770"; - case CHIP_RV730: return "RV730"; - case CHIP_RV710: return "RV710"; - case CHIP_RV740: return "RV740"; - case CHIP_CEDAR: return "CEDAR"; - case CHIP_REDWOOD: return "REDWOOD"; - case CHIP_JUNIPER: return "JUNIPER"; - case CHIP_CYPRESS: return "CYPRESS"; - case CHIP_HEMLOCK: return "HEMLOCK"; - default: return "unknown"; + case CHIP_R600: return "AMD R600"; + case CHIP_RV610: return "AMD RV610"; + case CHIP_RV630: return "AMD RV630"; + case CHIP_RV670: return "AMD RV670"; + case CHIP_RV620: return "AMD RV620"; + case CHIP_RV635: return "AMD RV635"; + case CHIP_RS780: return "AMD RS780"; + case CHIP_RS880: return "AMD RS880"; + case CHIP_RV770: return "AMD RV770"; + case CHIP_RV730: return "AMD RV730"; + case CHIP_RV710: return "AMD RV710"; + case CHIP_RV740: return "AMD RV740"; + case CHIP_CEDAR: return "AMD CEDAR"; + case CHIP_REDWOOD: return "AMD REDWOOD"; + case CHIP_JUNIPER: return "AMD JUNIPER"; + case CHIP_CYPRESS: return "AMD CYPRESS"; + case CHIP_HEMLOCK: return "AMD HEMLOCK"; + default: return "AMD unknown"; } } @@ -274,6 +277,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* Unsupported features (boolean caps). */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ return 0; @@ -429,6 +433,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen) if (rscreen == NULL) return; + + radeon_decref(rscreen->radeon); + FREE(rscreen); } diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index d152285815c..7a2d1f44122 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -35,7 +35,7 @@ struct r600_transfer { /* Buffer transfer. */ struct pipe_transfer *buffer_transfer; unsigned offset; - struct pipe_resource *linear_texture; + struct pipe_resource *staging_texture; }; /* This gets further specialized into either buffer or texture @@ -45,8 +45,6 @@ struct r600_transfer { struct r600_resource { struct u_resource base; struct r600_bo *bo; - u32 domain; - u32 flink; u32 size; }; @@ -68,9 +66,6 @@ struct r600_resource_texture { void r600_init_screen_resource_functions(struct pipe_screen *screen); -/* r600_buffer */ -u32 r600_domain_from_usage(unsigned usage); - /* r600_texture */ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ); diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 4106587398b..f6153c0e80f 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -218,7 +218,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s /* copy new shader */ if (shader->bo == NULL) { - shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0); + shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0); if (shader->bo == NULL) { return -ENOMEM; } @@ -2663,7 +2663,18 @@ static int tgsi_r600_arl(struct r600_shader_ctx *ctx) int r; memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + break; + case TGSI_OPCODE_ARR: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA; + break; + default: + assert(0); + return -1; + } + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) @@ -3070,7 +3081,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_r600_arl}, {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index b3e0d493217..54cc79b1549 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -469,12 +469,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - tmp = (unsigned)(state->line_width * 8.0); + tmp = (unsigned)state->line_width * 8; r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, 0x00000005, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MPASS_PS_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); + + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); @@ -1018,6 +1023,13 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 1c1978f8abb..1be5b156d35 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -472,7 +472,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); + //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 4ebd5b754b3..e719f7fb983 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,6 +31,7 @@ #include <util/u_inlines.h> #include <util/u_memory.h> #include "state_tracker/drm_driver.h" +#include "pipebuffer/pb_buffer.h" #include "r600_pipe.h" #include "r600_resource.h" #include "r600_state_inlines.h" @@ -39,8 +40,8 @@ extern struct u_resource_vtbl r600_texture_vtbl; -/* Copy from a tiled texture to a detiled one. */ -static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a full GPU texture to a transfer's staging one. */ +static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -48,15 +49,15 @@ static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_t subdst.face = 0; subdst.level = 0; - ctx->resource_copy_region(ctx, rtransfer->linear_texture, + ctx->resource_copy_region(ctx, rtransfer->staging_texture, subdst, 0, 0, 0, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, transfer->box.width, transfer->box.height); } -/* Copy from a detiled texture to a tiled one. */ -static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a transfer's staging texture to a full GPU one. */ +static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -66,7 +67,7 @@ static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_t subsrc.level = 0; ctx->resource_copy_region(ctx, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, - rtransfer->linear_texture, subsrc, + rtransfer->staging_texture, subsrc, 0, 0, 0, transfer->box.width, transfer->box.height); @@ -168,6 +169,10 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen, stride = util_format_get_stride(ptex->format, width); if (chipc == EVERGREEN) stride = align(stride, 512); + + if (ptex->bind & PIPE_BIND_RENDER_TARGET) + stride = align(stride, 512); + return stride; } @@ -283,7 +288,6 @@ r600_texture_create_object(struct pipe_screen *screen, pipe_reference_init(&resource->base.b.reference, 1); resource->base.b.screen = screen; resource->bo = bo; - resource->domain = r600_domain_from_usage(resource->base.b.bind); rtex->pitch_override = pitch_in_bytes_override; if (array_mode) @@ -293,7 +297,7 @@ r600_texture_create_object(struct pipe_screen *screen, resource->size = rtex->size; if (!resource->bo) { - resource->bo = r600_bo(radeon, rtex->size, 4096, 0); + resource->bo = r600_bo(radeon, rtex->size, 4096, base->bind, base->usage); if (!resource->bo) { FREE(rtex); return NULL; @@ -306,8 +310,14 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ) { unsigned array_mode = 0; + static int force_tiling = -1; - if (debug_get_bool_option("R600_FORCE_TILING", FALSE)) { + /* Would like some magic "get_bool_option_once" routine. + */ + if (force_tiling == -1) + force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE); + + if (force_tiling) { if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && !(templ->bind & PIPE_BIND_SCANOUT)) { array_mode = V_038000_ARRAY_2D_TILED_THIN1; @@ -335,6 +345,18 @@ static void r600_texture_destroy(struct pipe_screen *screen, FREE(rtex); } +static boolean r600_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *ptex, + struct winsys_handle *whandle) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; + struct r600_resource *resource = &rtex->resource; + struct radeon *radeon = (struct radeon *)screen->winsys; + + return r600_bo_get_winsys_handle(radeon, resource->bo, + rtex->pitch_in_bytes[0], whandle); +} + static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, struct pipe_resource *texture, unsigned face, unsigned level, @@ -434,10 +456,59 @@ int r600_texture_depth_flush(struct pipe_context *ctx, } out: + /* XXX: only do this if the depth texture has actually changed: + */ r600_blit_uncompress_depth_ptr(ctx, rtex); return 0; } +/* Needs adjustment for pixelformat: + */ +static INLINE unsigned u_box_volume( const struct pipe_box *box ) +{ + return box->width * box->depth * box->height; +}; + + +/* Figure out whether u_blitter will fallback to a transfer operation. + * If so, don't use a staging resource. + */ +static boolean permit_hardware_blit(struct pipe_screen *screen, + struct pipe_resource *res) +{ + unsigned bind; + + if (util_format_is_depth_or_stencil(res->format)) + bind = PIPE_BIND_DEPTH_STENCIL; + else + bind = PIPE_BIND_RENDER_TARGET; + + /* See r600_resource_copy_region: there is something wrong + * with depth resource copies at the moment so avoid them for + * now. + */ + if (util_format_get_component_bits(res->format, + UTIL_FORMAT_COLORSPACE_ZS, + 0) != 0) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + bind, 0)) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + PIPE_BIND_SAMPLER_VIEW, 0)) + return FALSE; + + return TRUE; +} + struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource *texture, struct pipe_subresource sr, @@ -448,6 +519,36 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource resource; struct r600_transfer *trans; int r; + boolean use_staging_texture = FALSE; + + /* We cannot map a tiled texture directly because the data is + * in a different order, therefore we do detiling using a blit. + * + * Also, use a temporary in GTT memory for read transfers, as + * the CPU is much happier reading out of cached system memory + * than uncached VRAM. + */ + if (rtex->tiled) + use_staging_texture = TRUE; + + if ((usage & PIPE_TRANSFER_READ) && + u_box_volume(box) > 1024) + use_staging_texture = TRUE; + + /* XXX: Use a staging texture for uploads if the underlying BO + * is busy. No interface for checking that currently? so do + * it eagerly whenever the transfer doesn't require a readback + * and might block. + */ + if ((usage & PIPE_TRANSFER_WRITE) && + !(usage & (PIPE_TRANSFER_READ | + PIPE_TRANSFER_DONTBLOCK | + PIPE_TRANSFER_UNSYNCHRONIZED))) + use_staging_texture = TRUE; + + if (!permit_hardware_blit(ctx->screen, texture) || + (texture->flags & R600_RESOURCE_FLAG_TRANSFER)) + use_staging_texture = FALSE; trans = CALLOC_STRUCT(r600_transfer); if (trans == NULL) @@ -457,6 +558,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.usage = usage; trans->transfer.box = *box; if (rtex->depth) { + /* XXX: only readback the rectangle which is being mapped? + */ + /* XXX: when discard is true, no need to read back from depth texture + */ r = r600_texture_depth_flush(ctx, texture); if (r < 0) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); @@ -464,7 +569,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, FREE(trans); return NULL; } - } else if (rtex->tiled) { + } else if (use_staging_texture) { resource.target = PIPE_TEXTURE_2D; resource.format = texture->format; resource.width0 = box->width; @@ -472,7 +577,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.depth0 = 1; resource.last_level = 0; resource.nr_samples = 0; - resource.usage = PIPE_USAGE_DYNAMIC; + resource.usage = PIPE_USAGE_STAGING; resource.bind = 0; resource.flags = R600_RESOURCE_FLAG_TRANSFER; /* For texture reading, the temporary (detiled) texture is used as @@ -486,8 +591,8 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.bind |= PIPE_BIND_SAMPLER_VIEW; } /* Create the temporary texture. */ - trans->linear_texture = ctx->screen->resource_create(ctx->screen, &resource); - if (trans->linear_texture == NULL) { + trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource); + if (trans->staging_texture == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); @@ -495,11 +600,9 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, } trans->transfer.stride = - ((struct r600_resource_texture *)trans->linear_texture)->pitch_in_bytes[0]; + ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0]; if (usage & PIPE_TRANSFER_READ) { - /* We cannot map a tiled texture directly because the data is - * in a different order, therefore we do detiling using a blit. */ - r600_copy_from_tiled_texture(ctx, trans); + r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ ctx->flush(ctx, 0, NULL); } @@ -516,11 +619,11 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; - if (rtransfer->linear_texture) { + if (rtransfer->staging_texture) { if (transfer->usage & PIPE_TRANSFER_WRITE) { - r600_copy_into_tiled_texture(ctx, rtransfer); + r600_copy_from_staging_texture(ctx, rtransfer); } - pipe_resource_reference(&rtransfer->linear_texture, NULL); + pipe_resource_reference(&rtransfer->staging_texture, NULL); } if (rtex->flushed_depth_texture) { pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); @@ -537,10 +640,11 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, enum pipe_format format = transfer->resource->format; struct radeon *radeon = (struct radeon *)ctx->screen->winsys; unsigned offset = 0; + unsigned usage = 0; char *map; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -553,7 +657,30 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, transfer->box.y / util_format_get_blockheight(format) * transfer->stride + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } - map = r600_bo_map(radeon, bo, 0, ctx); + + if (transfer->usage & PIPE_TRANSFER_WRITE) { + usage |= PB_USAGE_CPU_WRITE; + + if (transfer->usage & PIPE_TRANSFER_DISCARD) { + } + + if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) { + } + } + + if (transfer->usage & PIPE_TRANSFER_READ) { + usage |= PB_USAGE_CPU_READ; + } + + if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { + usage |= PB_USAGE_DONTBLOCK; + } + + if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) { + usage |= PB_USAGE_UNSYNCHRONIZED; + } + + map = r600_bo_map(radeon, bo, usage, ctx); if (!map) { return NULL; } @@ -568,8 +695,8 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct radeon *radeon = (struct radeon *)ctx->screen->winsys; struct r600_bo *bo; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -584,7 +711,7 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct u_resource_vtbl r600_texture_vtbl = { - u_default_resource_get_handle, /* get_handle */ + r600_texture_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ @@ -689,7 +816,7 @@ uint32_t r600_translate_texformat(enum pipe_format format, result = FMT_24_8; goto out_word4; case PIPE_FORMAT_S8_USCALED: - result = V_0280A0_COLOR_8; + result = FMT_8; word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); goto out_word4; default: @@ -718,7 +845,29 @@ uint32_t r600_translate_texformat(enum pipe_format format, /* S3TC formats. TODO */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { - goto out_unknown; + static int r600_enable_s3tc = -1; + + if (r600_enable_s3tc == -1) + r600_enable_s3tc = + debug_get_bool_option("R600_ENABLE_S3TC", FALSE); + + if (!r600_enable_s3tc) + goto out_unknown; + + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + result = FMT_BC1; + goto out_word4; + case PIPE_FORMAT_DXT3_RGBA: + result = FMT_BC2; + goto out_word4; + case PIPE_FORMAT_DXT5_RGBA: + result = FMT_BC3; + goto out_word4; + default: + goto out_unknown; + } } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index a3cb5b86004..ae19bfb8285 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -2100,6 +2100,10 @@ #define G_028C00_LAST_PIXEL(x) (((x) >> 10) & 0x1) #define C_028C00_LAST_PIXEL 0xFFFFFBFF #define R_028C04_PA_SC_AA_CONFIG 0x028C04 +#define R_028C08_PA_SU_VTX_CNTL 0x028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C #define R_028C48_PA_SC_AA_MASK 0x028C48 #define R_028810_PA_CL_CLIP_CNTL 0x028810 diff --git a/src/gallium/drivers/rbug/README b/src/gallium/drivers/rbug/README index b6d3a5cf351..9d7bd4e7695 100644 --- a/src/gallium/drivers/rbug/README +++ b/src/gallium/drivers/rbug/README @@ -7,24 +7,10 @@ This directory contains a Gallium3D remote debugger pipe driver. It provides remote debugging functionality. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri +Do - export XMESA_TRACE=y GALLIUM_RBUG=true progs/trivial/tri which should open gallium remote debugging session. While the program is running diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript index 3da6ac104a4..169c2718dc3 100644 --- a/src/gallium/drivers/rbug/SConscript +++ b/src/gallium/drivers/rbug/SConscript @@ -11,4 +11,6 @@ rbug = env.ConvenienceLibrary( 'rbug_screen.c', ]) +env.Alias('rbug', rbug) + Export('rbug') diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index dea7f885e0d..9b2abdfd7f1 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -38,4 +38,6 @@ softpipe = env.ConvenienceLibrary( 'sp_video_context.c', ]) +env.Alias('softpipe', softpipe) + Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index c8f5f89568a..89b2a91fc1f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -860,6 +860,7 @@ choose_depth_test(struct quad_stage *qs, /* look for special cases */ if (!alpha && !depth && + !occlusion && !stencil) { qs->run = depth_noop; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index edc2a6dacf2..5e13d632387 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -65,7 +65,12 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return PIPE_MAX_SAMPLERS; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: +#ifdef HAVE_LLVM + /* Softpipe doesn't yet know how to tell draw/llvm about textures */ + return 0; +#else return PIPE_MAX_VERTEX_SAMPLERS; +#endif case PIPE_CAP_MAX_COMBINED_SAMPLERS: return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: diff --git a/src/gallium/drivers/sw/SConscript b/src/gallium/drivers/sw/SConscript index e9ebf751ddd..40d01db2f6d 100644 --- a/src/gallium/drivers/sw/SConscript +++ b/src/gallium/drivers/sw/SConscript @@ -20,7 +20,6 @@ if True: if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') env.Prepend(LIBS = [llvmpipe]) extra.append(llvmpipe) diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index cdcd8d2b4be..c210cba032a 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -7,23 +7,8 @@ This directory contains a Gallium3D trace debugger pipe driver. It can traces all incoming calls. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri - == Tracing == For tracing then do @@ -40,6 +25,7 @@ For remote debugging see: src/gallium/drivers/rbug/README + = Integrating = You can integrate the trace pipe driver either inside the state tracker or the @@ -60,5 +46,5 @@ are automatically wrapped by trace_screen. -- -Jose Fonseca <[email protected]> +Jose Fonseca <[email protected]> Jakob Bornecrantz <[email protected]> diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 06b0c4863a4..1384fe33d72 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -12,4 +12,6 @@ trace = env.ConvenienceLibrary( 'tr_texture.c', ]) +env.Alias('trace', trace) + Export('trace') |