diff options
Diffstat (limited to 'src/gallium/drivers')
35 files changed, 606 insertions, 431 deletions
diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index 7816925d230..e05b059706d 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -181,8 +181,7 @@ i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) return I915_TILE_NONE; if (util_format_is_s3tc(tex->b.b.format)) - /* XXX X-tiling might make sense */ - return I915_TILE_NONE; + return I915_TILE_X; if (is->debug.use_blitter) return I915_TILE_X; diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 0f4327fdc81..0e427749636 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -28,6 +28,7 @@ #include "draw/draw_context.h" #include "util/u_format.h" +#include "util/u_format_s3tc.h" #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_string.h" @@ -267,6 +268,10 @@ i915_is_format_supported(struct pipe_screen *screen, PIPE_FORMAT_YUYV, /* XXX why not? PIPE_FORMAT_Z16_UNORM, */ + PIPE_FORMAT_DXT1_RGB, + PIPE_FORMAT_DXT1_RGBA, + PIPE_FORMAT_DXT3_RGBA, + PIPE_FORMAT_DXT5_RGBA, PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_NONE /* list terminator */ @@ -432,5 +437,7 @@ i915_screen_create(struct i915_winsys *iws) i915_debug_init(is); + util_format_s3tc_init(); + return &is->base; } diff --git a/src/gallium/drivers/i915/i915_state_sampler.c b/src/gallium/drivers/i915/i915_state_sampler.c index 916cb767536..be70e7a92c9 100644 --- a/src/gallium/drivers/i915/i915_state_sampler.c +++ b/src/gallium/drivers/i915/i915_state_sampler.c @@ -223,15 +223,13 @@ static uint translate_texture_format(enum pipe_format pipeFormat) #endif case PIPE_FORMAT_Z16_UNORM: return (MAPSURF_16BIT | MT_16BIT_L16); -#if 0 - case PIPE_FORMAT_RGBA_DXT1: - case PIPE_FORMAT_RGB_DXT1: + case PIPE_FORMAT_DXT1_RGBA: + case PIPE_FORMAT_DXT1_RGB: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); - case PIPE_FORMAT_RGBA_DXT3: + case PIPE_FORMAT_DXT3_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); - case PIPE_FORMAT_RGBA_DXT5: + case PIPE_FORMAT_DXT5_RGBA: return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); -#endif case PIPE_FORMAT_Z24_UNORM_S8_USCALED: case PIPE_FORMAT_Z24X8_UNORM: return (MAPSURF_32BIT | MT_32BIT_xI824); diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index c82ab821c7e..cbe06e58a78 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -1065,6 +1065,8 @@ lp_setup_begin_query(struct lp_setup_context *setup, set_scene_state(setup, SETUP_ACTIVE, "begin_query"); + setup->active_query = pq; + if (setup->scene) { if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_BEGIN_QUERY, @@ -1080,8 +1082,6 @@ lp_setup_begin_query(struct lp_setup_context *setup, } } } - - setup->active_query = pq; } diff --git a/src/gallium/drivers/nouveau/nouveau_mm.c b/src/gallium/drivers/nouveau/nouveau_mm.c index 7edeb4d21d6..6c6d28c17f6 100644 --- a/src/gallium/drivers/nouveau/nouveau_mm.c +++ b/src/gallium/drivers/nouveau/nouveau_mm.c @@ -143,7 +143,7 @@ mm_slab_new(struct nouveau_mman *cache, int chunk_order) cache->allocated += size; - debug_printf("MM: new slab, total memory = %lu KiB\n", + debug_printf("MM: new slab, total memory = %llu KiB\n", cache->allocated / 1024); return PIPE_OK; diff --git a/src/gallium/drivers/nv50/nv50_formats.c b/src/gallium/drivers/nv50/nv50_formats.c index c65189d0671..96ed9a7d6d4 100644 --- a/src/gallium/drivers/nv50/nv50_formats.c +++ b/src/gallium/drivers/nv50/nv50_formats.c @@ -571,4 +571,22 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index 9eeca05ada3..486b368ae98 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -158,6 +158,9 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x6000; break; default: + if (pt->bind & PIPE_BIND_CURSOR) + tile_flags = 0; + else if ((pt->bind & PIPE_BIND_SCANOUT) && util_format_get_blocksizebits(pt->format) == 32) tile_flags = 0x7a00; @@ -165,6 +168,8 @@ nv50_miptree_create(struct pipe_screen *pscreen, tile_flags = 0x7000; break; } + if (pt->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR)) + tile_flags |= NOUVEAU_BO_TILE_SCANOUT; /* For 3D textures, a mipmap is spanned by all the layers, for array * textures and cube maps, each layer contains its own mipmaps. @@ -176,7 +181,10 @@ nv50_miptree_create(struct pipe_screen *pscreen, unsigned blocksize = util_format_get_blocksize(pt->format); lvl->offset = mt->total_size; - lvl->tile_mode = get_tile_dims(nbx, nby, d); + + if (tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) + lvl->tile_mode = get_tile_dims(nbx, nby, d); + lvl->pitch = align(nbx * blocksize, NV50_TILE_PITCH(lvl->tile_mode)); mt->total_size += lvl->pitch * diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 641ad7e2780..4dad8599870 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -89,7 +89,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: - return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP: + return nv50_screen(pscreen)->tesla->grclass >= NVA0_3D; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -417,6 +420,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(BLEND_SEPARATE_ALPHA), 1); OUT_RING (chan, 1); + if (tesla_class >= NVA0_3D) { + BEGIN_RING(chan, RING_3D_(NVA0_3D_TEX_MISC), 1); + OUT_RING (chan, NVA0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); + } + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); @@ -469,7 +477,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) screen->tls_size = tls_space * max_warps * 32; - debug_printf("max_warps = %i, tls_size = %lu KiB\n", + debug_printf("max_warps = %i, tls_size = %llu KiB\n", max_warps, screen->tls_size >> 10); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 16, screen->tls_size, diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 799f49619d2..8d75dd07c4d 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -34,6 +34,36 @@ #include "nouveau/nouveau_gldefs.h" +/* Caveats: + * ! pipe_sampler_state.normalized_coords is ignored - rectangle textures will + * use non-normalized coordinates, everything else won't + * (The relevant bit is in the TIC entry and not the TSC entry.) + * + * ! pipe_sampler_state.seamless_cube_map is ignored - seamless filtering is + * always activated on NVA0 + + * (Give me the global bit, otherwise it's not worth the CPU work.) + * + * ! pipe_sampler_state.border_color is not swizzled according to the texture + * swizzle in pipe_sampler_view + * (This will be ugly with indirect independent texture/sampler access, + * we'd have to emulate the logic in the shader. GL doesn't have that, + * D3D doesn't have swizzle, if we knew what we were implementing we'd be + * good.) + * + * ! pipe_rasterizer_state.line_last_pixel is ignored - it is never drawn + * + * ! pipe_rasterizer_state.flatshade_first also applies to QUADS + * (There's a GL query for that, forcing an exception is just ridiculous.) + * + * ! pipe_rasterizer_state.gl_rasterization_rules is ignored - pixel centers + * are always at half integer coordinates and the top-left rule applies + * (There does not seem to be a hardware switch for this.) + * + * ! pipe_rasterizer_state.sprite_coord_enable is masked with 0xff on NVC0 + * (The hardware only has 8 slots meant for TexCoord and we have to assign + * in advance to maintain elegant separate shader objects.) + */ + static INLINE uint32_t nv50_colormask(unsigned mask) { diff --git a/src/gallium/drivers/nvc0/nvc0_formats.c b/src/gallium/drivers/nvc0/nvc0_formats.c index 678e9b563ee..81077a7fa80 100644 --- a/src/gallium/drivers/nvc0/nvc0_formats.c +++ b/src/gallium/drivers/nvc0/nvc0_formats.c @@ -576,4 +576,22 @@ const struct nvc0_format nvc0_format_table[PIPE_FORMAT_COUNT] = [PIPE_FORMAT_A8B8G8R8_UNORM] = { 0, B_(C3, C2, C1, C0, UNORM, UNORM, UNORM, UNORM, 8_8_8_8, 0), SAMPLER_VIEW }, + + /* FIXED FORMATS - hw doesn't support these, convert on vbo push for now */ + + [PIPE_FORMAT_R32G32B32A32_FIXED] = { 0, + B_(C0, C1, C2, C3, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32B32_FIXED] = { 0, + B_(C0, C1, C2, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32G32_FIXED] = { 0, + B_(C0, C1, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32_32, 0), + VERTEX_BUFFER }, + + [PIPE_FORMAT_R32_FIXED] = { 0, + B_(C0, ZERO, ZERO, ONE_FLOAT, FLOAT, FLOAT, FLOAT, FLOAT, 32, 0), + VERTEX_BUFFER }, }; diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index ca0691d2aee..34bf0f0a2ad 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -74,7 +74,10 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_SHADOW_MAP: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_ANISOTROPIC_FILTER: + case PIPE_CAP_SEAMLESS_CUBE_MAP: return 1; + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return 0; case PIPE_CAP_TWO_SIDED_STENCIL: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: @@ -441,6 +444,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RING (chan, 1); BEGIN_RING(chan, RING_3D(BLEND_ENABLE_COMMON), 1); OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(TEX_MISC), 1); + OUT_RING (chan, NVC0_3D_TEX_MISC_SEAMLESS_CUBE_MAP); nvc0_magic_3d_init(chan); diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 9ec16c6562f..7a1366a4f8f 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -113,14 +113,21 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: - case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - return is_r500 ? 1 : 0; + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: + return 1; + + /* r300 cannot do swizzling of compressed textures. Supported otherwise. */ case PIPE_CAP_TEXTURE_SWIZZLE: return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; + + /* Supported on r500 only. */ + case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_SM3: return is_r500 ? 1 : 0; - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_DUAL_SOURCE_BLEND: case PIPE_CAP_INDEP_BLEND_ENABLE: @@ -130,6 +137,11 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_ARRAY_TEXTURES: case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: return 0; /* SWTCL-only features. */ @@ -141,8 +153,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: case PIPE_CAP_MAX_COMBINED_SAMPLERS: return r300screen->caps.num_tex_units; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - return 0; case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: @@ -153,16 +163,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_MAX_RENDER_TARGETS: return 4; - /* General shader limits and features. */ - case PIPE_CAP_SM3: - return is_r500 ? 1 : 0; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; default: debug_printf("r300: Warning: Unknown CAP %d in get_param.\n", param); diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c index 6a000cfe2c6..0561ab9bfa4 100644 --- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c +++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c @@ -266,6 +266,7 @@ static void transform_texture(struct rc_instruction * dst, struct tgsi_instructi *shadowSamplers |= 1 << dst->U.I.TexSrcUnit; break; } + dst->U.I.TexSwizzle = RC_SWIZZLE_XYZW; } static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src) diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile index 436de9c4dbd..3dda3a6339f 100644 --- a/src/gallium/drivers/r600/Makefile +++ b/src/gallium/drivers/r600/Makefile @@ -10,7 +10,6 @@ C_SOURCES = \ r600_asm.c \ r600_blit.c \ r600_buffer.c \ - r600_helper.c \ r600_pipe.c \ r600_query.c \ r600_resource.c \ diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index 5a5fa6d65fd..0135808f10a 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -19,7 +19,6 @@ r600 = env.ConvenienceLibrary( 'r600_asm.c', 'r600_buffer.c', 'r600_blit.c', - 'r600_helper.c', 'r600_pipe.c', 'r600_query.c', 'r600_resource.c', diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index f20d45f48de..a2ba73febdd 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -348,7 +348,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_028C70_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -367,6 +367,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_B10G10R10A2_UNORM: return V_028C70_SWAP_ALT; + case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R32_FLOAT: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R16G16_UNORM: @@ -469,6 +470,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16G16_UNORM: return V_028C70_COLOR_16_16; + case PIPE_FORMAT_R11G11B10_FLOAT: + return V_028C70_COLOR_10_11_11_FLOAT; + /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: case PIPE_FORMAT_R16G16B16A16_USCALED: @@ -502,60 +506,60 @@ 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. */ } } static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_BIG_ENDIAN - switch(colorformat) { - case V_0280A0_COLOR_4_4: - return(ENDIAN_NONE); - - /* 8-bit buffers. */ - case V_0280A0_COLOR_8: - return(ENDIAN_NONE); - - /* 16-bit buffers. */ - case V_0280A0_COLOR_5_6_5: - case V_0280A0_COLOR_1_5_5_5: - case V_0280A0_COLOR_4_4_4_4: - case V_0280A0_COLOR_16: - case V_0280A0_COLOR_8_8: - return(ENDIAN_8IN16); - - /* 32-bit buffers. */ - case V_0280A0_COLOR_8_8_8_8: - case V_0280A0_COLOR_2_10_10_10: - case V_0280A0_COLOR_8_24: - case V_0280A0_COLOR_24_8: - case V_0280A0_COLOR_32_FLOAT: - case V_0280A0_COLOR_16_16_FLOAT: - case V_0280A0_COLOR_16_16: - return(ENDIAN_8IN32); - - /* 64-bit buffers. */ - case V_0280A0_COLOR_16_16_16_16: - case V_0280A0_COLOR_16_16_16_16_FLOAT: - return(ENDIAN_8IN16); - - case V_0280A0_COLOR_32_32_FLOAT: - case V_0280A0_COLOR_32_32: - return(ENDIAN_8IN32); - - /* 128-bit buffers. */ - case V_0280A0_COLOR_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32: - return(ENDIAN_8IN32); - default: - return ENDIAN_NONE; /* Unsupported. */ + if (R600_BIG_ENDIAN) { + switch(colorformat) { + case V_028C70_COLOR_4_4: + return(ENDIAN_NONE); + + /* 8-bit buffers. */ + case V_028C70_COLOR_8: + return(ENDIAN_NONE); + + /* 16-bit buffers. */ + case V_028C70_COLOR_5_6_5: + case V_028C70_COLOR_1_5_5_5: + case V_028C70_COLOR_4_4_4_4: + case V_028C70_COLOR_16: + case V_028C70_COLOR_8_8: + return(ENDIAN_8IN16); + + /* 32-bit buffers. */ + case V_028C70_COLOR_8_8_8_8: + case V_028C70_COLOR_2_10_10_10: + case V_028C70_COLOR_8_24: + case V_028C70_COLOR_24_8: + case V_028C70_COLOR_32_FLOAT: + case V_028C70_COLOR_16_16_FLOAT: + case V_028C70_COLOR_16_16: + return(ENDIAN_8IN32); + + /* 64-bit buffers. */ + case V_028C70_COLOR_16_16_16_16: + case V_028C70_COLOR_16_16_16_16_FLOAT: + return(ENDIAN_8IN16); + + case V_028C70_COLOR_32_32_FLOAT: + case V_028C70_COLOR_32_32: + return(ENDIAN_8IN32); + + /* 128-bit buffers. */ + case V_028C70_COLOR_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32_FLOAT: + case V_028C70_COLOR_32_32_32_32: + return(ENDIAN_8IN32); + default: + return ENDIAN_NONE; /* Unsupported. */ + } + } else { + return ENDIAN_NONE; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index a972f82fb1d..502f2663e8b 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -143,14 +143,17 @@ static void *evergreen_create_blend_state(struct pipe_context *ctx, static void *evergreen_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -190,6 +193,7 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -206,7 +210,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, @@ -307,16 +310,11 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -328,14 +326,13 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 8)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 8)), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) | - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | + (state->seamless_cube_map ? 0 : S_03C008_DISABLE_CUBE_WRAP(1)) | S_03C008_TYPE(1), 0xFFFFFFFF, NULL); @@ -409,7 +406,6 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte array_mode = tmp->array_mode[0]; tile_type = tmp->tile_type; - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0, S_030000_DIM(r600_tex_dim(texture->target)) | S_030000_PITCH((pitch / 8) - 1) | @@ -715,12 +711,26 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state S_028C70_ENDIAN(endian); - /* we can only set the export size if any thing is snorm/unorm component is > 11 bits, - if we aren't a float, sint or uint */ + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases. + * EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ + /* FIXME: This should probably be the same for all CBs if we want + * useful alpha tests. */ if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && - desc->channel[i].size < 12 && desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && - ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_028C70_NUMBER_UINT && ntype != V_028C70_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) { color_info |= S_028C70_SOURCE_FORMAT(V_028C70_EXPORT_4C_16BPC); + rctx->export_16bpc = true; + } else { + rctx->export_16bpc = false; + } + rctx->alpha_ref_dirty = true; if (rtex->array_mode[level] > V_028C70_ARRAY_LINEAR_ALIGNED) { tile_type = rtex->tile_type; @@ -922,7 +932,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = evergreen_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; @@ -1232,9 +1242,11 @@ void evergreen_init_config(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(rstate, R_009100_SPI_CONFIG_CNTL, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00913C_SPI_CONFIG_CNTL_1, S_00913C_VTX_DONE_DELAY(4), 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); +#if 0 + r600_pipe_state_add_reg(rstate, R_028350_SX_MISC, 0x0, 0xFFFFFFFF, NULL); -// r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0x0, 0xFFFFFFFF, NULL); +#endif r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MODE_CNTL_0, 0x0, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A4C_PA_SC_MODE_CNTL_1, 0x0, 0xFFFFFFFF, NULL); @@ -1574,9 +1586,7 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_030008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_030008_ENDIAN_SWAP(r600_endian_swap(32)) | S_030008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3, S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) | diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index de445b879a1..670606d9b07 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1194,6 +1194,15 @@ #define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 21) #define G_03C008_FORCE_DEGAMMA(x) (((x) >> 21) & 0x1) #define C_03C008_FORCE_DEGAMMA 0xFFDFFFFF +#define S_03C008_ANISO_BIAS(x) (((x) & 0x3f) << 22) +#define G_03C008_ANISO_BIAS(x) (((x) >> 22) & 0x3f) +#define C_03C008_ANISO_BIAS (~(0x3f << 22)) +#define S_03C008_TRUNCATE_COORD(x) (((x) & 0x1) << 28) +#define G_03C008_TRUNCATE_COORD(x) (((x) >> 28) & 0x1) +#define C_03C008_TRUNCATE_COORD (~(1 << 28)) +#define S_03C008_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 29) +#define G_03C008_DISABLE_CUBE_WRAP(x) (((x) >> 29) & 0x1) +#define C_03C008_DISABLE_CUBE_WRAP (~(1 << 29)) #define S_03C008_TYPE(x) (((x) & 0x1) << 31) #define G_03C008_TYPE(x) (((x) >> 31) & 0x1) #define C_03C008_TYPE 0x7FFFFFFF diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 0b0df9d019b..33aa45088a8 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -235,6 +235,7 @@ struct r600_query { #define R600_CONTEXT_DRAW_PENDING (1 << 0) #define R600_CONTEXT_DST_CACHES_DIRTY (1 << 1) +#define R600_CONTEXT_CHECK_EVENT_FLUSH (1 << 2) struct r600_context { struct radeon *radeon; diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 7e854b1b81d..033e84665f5 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -33,12 +33,6 @@ #include "r600_formats.h" #include "r600d.h" -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - #define NUM_OF_CYCLES 3 #define NUM_OF_COMPONENTS 4 @@ -531,19 +525,19 @@ static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first, else if (is_alu_vec_unit_inst(bc, alu)) trans = 0; else if (assignment[chan]) - trans = 1; // assume ALU_INST_PREFER_VECTOR + trans = 1; /* Assume ALU_INST_PREFER_VECTOR. */ else trans = 0; if (trans) { if (assignment[4]) { - assert(0); //ALU.Trans has already been allocated + assert(0); /* ALU.Trans has already been allocated. */ return -1; } assignment[4] = alu; } else { if (assignment[chan]) { - assert(0); //ALU.chan has already been allocated + assert(0); /* ALU.chan has already been allocated. */ return -1; } assignment[chan] = alu; @@ -595,7 +589,7 @@ static int reserve_gpr(struct alu_bank_swizzle *bs, unsigned sel, unsigned chan, if (bs->hw_gpr[cycle][chan] == -1) bs->hw_gpr[cycle][chan] = sel; else if (bs->hw_gpr[cycle][chan] != (int)sel) { - // Another scalar operation has already used GPR read port for channel + /* Another scalar operation has already used the GPR read port for the channel. */ return -1; } return 0; @@ -615,9 +609,9 @@ static int reserve_cfile(struct r600_bc *bc, struct alu_bank_swizzle *bs, unsign return 0; } else if (bs->hw_cfile_addr[res] == sel && bs->hw_cfile_elem[res] == chan) - return 0; // Read for this scalar element already reserved, nothing to do here. + return 0; /* Read for this scalar element already reserved, nothing to do here. */ } - // All cfile read ports are used, cannot reference vector element + /* All cfile read ports are used, cannot reference vector element. */ return -1; } @@ -632,8 +626,8 @@ static int is_gpr(unsigned sel) static int is_cfile(unsigned sel) { return (sel > 255 && sel < 512) || - (sel > 511 && sel < 4607) || // Kcache before translate - (sel > 127 && sel < 192); // Kcache after translate + (sel > 511 && sel < 4607) || /* Kcache before translation. */ + (sel > 127 && sel < 192); /* Kcache after translation. */ } static int is_const(int sel) @@ -655,8 +649,8 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_vec[bank_swizzle][src]; if (src == 1 && sel == alu->src[0].sel && elem == alu->src[0].chan) - // Nothing to do; special-case optimization, - // second source uses first source’s reservation + /* Nothing to do; special-case optimization, + * second source uses first source’s reservation. */ continue; else { r = reserve_gpr(bs, sel, elem, cycle); @@ -668,7 +662,7 @@ static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, if (r) return r; } - // No restrictions on PV, PS, literal or special constants + /* No restrictions on PV, PS, literal or special constants. */ } return 0; } @@ -682,10 +676,10 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, for (const_count = 0, src = 0; src < num_src; ++src) { sel = alu->src[src].sel; elem = alu->src[src].chan; - if (is_const(sel)) { // Any constant, including literal and inline constants + if (is_const(sel)) { /* Any constant, including literal and inline constants. */ if (const_count >= 2) - // More than two references to a constant in - // transcendental operation. + /* More than two references to a constant in + * transcendental operation. */ return -1; else const_count++; @@ -702,15 +696,19 @@ static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, if (is_gpr(sel)) { cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; if (cycle < const_count) - // Cycle for GPR load conflicts with - // constant load in transcendental operation. + /* Cycle for GPR load conflicts with + * constant load in transcendental operation. */ return -1; r = reserve_gpr(bs, sel, elem, cycle); if (r) return r; } - // Constants already processed - // No restrictions on PV, PS + /* PV PS restrictions */ + if (const_count && (sel == 254 || sel == 255)) { + cycle = cycle_for_bank_swizzle_scl[bank_swizzle][src]; + if (cycle < const_count) + return -1; + } } return 0; } @@ -721,30 +719,36 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, struct alu_bank_swizzle bs; int bank_swizzle[5]; int i, r = 0, forced = 0; - - for (i = 0; i < 5; i++) + boolean scalar_only = true; + for (i = 0; i < 5; i++) { if (slots[i] && slots[i]->bank_swizzle_force) { slots[i]->bank_swizzle = slots[i]->bank_swizzle_force; forced = 1; } - + if (i < 4 && slots[i]) + scalar_only = false; + } if (forced) return 0; - // just check every possible combination of bank swizzle - // not very efficent, but works on the first try in most of the cases + /* Just check every possible combination of bank swizzle. + * Not very efficent, but works on the first try in most of the cases. */ for (i = 0; i < 4; i++) bank_swizzle[i] = SQ_ALU_VEC_012; bank_swizzle[4] = SQ_ALU_SCL_210; while(bank_swizzle[4] <= SQ_ALU_SCL_221) { init_bank_swizzle(&bs); - for (i = 0; i < 4; i++) { - if (slots[i]) { - r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); - if (r) - break; + if (scalar_only == false) { + for (i = 0; i < 4; i++) { + if (slots[i]) { + r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); + if (r) + break; + } } - } + } else + r = 0; + if (!r && slots[4]) { r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]); } @@ -756,16 +760,20 @@ static int check_and_set_bank_swizzle(struct r600_bc *bc, return 0; } - for (i = 0; i < 5; i++) { - bank_swizzle[i]++; - if (bank_swizzle[i] <= SQ_ALU_VEC_210) - break; - else - bank_swizzle[i] = SQ_ALU_VEC_012; + if (scalar_only) { + bank_swizzle[4]++; + } else { + for (i = 0; i < 5; i++) { + bank_swizzle[i]++; + if (bank_swizzle[i] <= SQ_ALU_VEC_210) + break; + else + bank_swizzle[i] = SQ_ALU_VEC_012; + } } } - // couldn't find a working swizzle + /* Couldn't find a working swizzle. */ return -1; } @@ -835,17 +843,17 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg) case -1: *sel = V_SQ_ALU_SRC_M_1_INT; break; - case 0x3F800000: // 1.0f + case 0x3F800000: /* 1.0f */ *sel = V_SQ_ALU_SRC_1; break; - case 0x3F000000: // 0.5f + case 0x3F000000: /* 0.5f */ *sel = V_SQ_ALU_SRC_0_5; break; - case 0xBF800000: // -1.0f + case 0xBF800000: /* -1.0f */ *sel = V_SQ_ALU_SRC_1; *neg ^= 1; break; - case 0xBF000000: // -0.5f + case 0xBF000000: /* -0.5f */ *sel = V_SQ_ALU_SRC_0_5; *neg ^= 1; break; @@ -938,13 +946,13 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; - // let's check used slots + /* Let's check used slots. */ if (prev[i] && !slots[i]) { result[i] = prev[i]; continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { - // trans unit is still free try to use it + /* Trans unit is still free try to use it. */ if (is_alu_any_unit_inst(bc, slots[i])) { result[i] = prev[i]; result[4] = slots[i]; @@ -963,14 +971,14 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], alu = slots[i]; num_once_inst += is_alu_once_inst(bc, alu); - // let's check dst gpr + /* Let's check dst gpr. */ if (alu->dst.rel) { if (have_mova) return 0; have_rel = 1; } - // let's check source gprs + /* Let's check source gprs */ num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { if (alu->src[src].rel) { @@ -979,7 +987,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], have_rel = 1; } - // constants doesn't matter + /* Constants don't matter. */ if (!is_gpr(alu->src[src].sel)) continue; @@ -987,7 +995,7 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], if (!prev[j] || !prev[j]->dst.write) continue; - // if it's relative then we can't determin which gpr is really used + /* If it's relative then we can't determin which gpr is really used. */ if (prev[j]->dst.chan == alu->src[src].chan && (prev[j]->dst.sel == alu->src[src].sel || prev[j]->dst.rel || alu->src[src].rel)) @@ -1390,7 +1398,7 @@ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsign S_SQ_VTX_WORD1_SRF_MODE_ALL(vtx->srf_mode_all) | S_SQ_VTX_WORD1_GPR_DST_GPR(vtx->dst_gpr); bc->bytecode[id++] = S_SQ_VTX_WORD2_OFFSET(vtx->offset) | - S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) | + S_SQ_VTX_WORD2_ENDIAN_SWAP(vtx->endian) | S_SQ_VTX_WORD2_MEGA_FETCH(1); bc->bytecode[id++] = 0; return 0; @@ -1927,7 +1935,7 @@ void r600_bc_dump(struct r600_bc *bc) fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); fprintf(stderr, "ENDIAN:%d ", vtx->endian); fprintf(stderr, "OFFSET:%d\n", vtx->offset); - //TODO + /* TODO */ id++; fprintf(stderr, "%04d %08X \n", id, bc->bytecode[id]); id++; @@ -1960,6 +1968,8 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, } } + *endian = r600_endian_swap(desc->channel[i].size); + switch (desc->channel[i].type) { /* Half-floats, floats, ints */ case UTIL_FORMAT_TYPE_FLOAT: @@ -1977,9 +1987,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -1996,9 +2003,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32_FLOAT; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2036,9 +2040,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_16_16_16_16; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN16; -#endif break; case 32: switch (desc->nr_channels) { @@ -2055,9 +2056,6 @@ static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, *format = FMT_32_32_32_32; break; } -#ifdef PIPE_ARCH_BIG_ENDIAN - *endian = ENDIAN_8IN32; -#endif break; default: goto out_unknown; @@ -2093,11 +2091,11 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru u32 *bytecode; int i, r; - /* vertex elements offset need special handling, if offset is bigger - + * than what we can put in fetch instruction then we need to alterate - * the vertex resource offset. In such case in order to simplify code - * we will bound one resource per elements. It's a worst case scenario. - */ + /* Vertex element offsets need special handling. If the offset is + * bigger than what we can put in the fetch instruction we need to + * alter the vertex resource offset. In order to simplify code we + * will bind one resource per element in such cases. It's a worst + * case scenario. */ for (i = 0; i < ve->count; i++) { ve->vbuffer_offset[i] = C_SQ_VTX_WORD2_OFFSET & elements[i].src_offset; if (ve->vbuffer_offset[i]) { @@ -2202,8 +2200,12 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru return -ENOMEM; } - for(i = 0; i < ve->fs_size / 4; i++) { - *(bytecode + i) = CPU_TO_LE32(*(bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < ve->fs_size / 4; ++i) { + bytecode[i] = bswap_32(bc.bytecode[i]); + } + } else { + memcpy(bytecode, bc.bytecode, ve->fs_size); } r600_bo_unmap(rctx->radeon, ve->fetch_shader); diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 71b47e1b056..72f352df3c3 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -81,18 +81,11 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, struct pipe_transfer *transfer) { struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource); - int write = 0; uint8_t *data; if (rbuffer->r.b.user_ptr) return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x; - if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { - /* FIXME */ - } - if (transfer->usage & PIPE_TRANSFER_WRITE) { - write = 1; - } data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe); if (!data) return NULL; @@ -268,31 +261,30 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour uint8_t *ptr = (*rbuffer)->r.b.user_ptr; unsigned size = (*rbuffer)->r.b.b.b.width0; boolean flushed; -#ifdef PIPE_ARCH_BIG_ENDIAN - int i; - uint32_t *tmpPtr; *rbuffer = NULL; - tmpPtr = (uint32_t *)malloc(size); - /* big endian swap */ - if(tmpPtr == NULL) { - return; - } - for(i = 0; i < size / 4; i++) { - tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i)); - } + if (R600_BIG_ENDIAN) { + uint32_t *tmpPtr; + unsigned i; - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); + if (!(tmpPtr = malloc(size))) { + R600_ERR("Failed to allocate BE swap buffer.\n"); + return; + } - free(tmpPtr); -#else - *rbuffer = NULL; + for (i = 0; i < size / 4; ++i) { + tmpPtr[i] = bswap_32(((uint32_t *)ptr)[i]); + } + + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); - u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, - (struct pipe_resource**)rbuffer, &flushed); -#endif + free(tmpPtr); + } else { + u_upload_data(rctx->vbuf_mgr->uploader, 0, size, ptr, const_offset, + (struct pipe_resource**)rbuffer, &flushed); + } } else { *const_offset = 0; } diff --git a/src/gallium/drivers/r600/r600_formats.h b/src/gallium/drivers/r600/r600_formats.h index 0c91a212384..ae0bc432ad2 100644 --- a/src/gallium/drivers/r600/r600_formats.h +++ b/src/gallium/drivers/r600/r600_formats.h @@ -1,6 +1,8 @@ #ifndef R600_FORMATS_H #define R600_FORMATS_H +#include "r600_pipe.h" + /* list of formats from R700 ISA document - apply across GPUs in different registers */ #define FMT_INVALID 0x00000000 #define FMT_8 0x00000001 @@ -52,5 +54,31 @@ #define FMT_BC3 0x00000033 #define FMT_BC4 0x00000034 #define FMT_BC5 0x00000035 +#define FMT_BC6 0x00000036 +#define FMT_BC7 0x00000037 +#define FMT_32_AS_32_32_32_32 0x00000038 + +#define ENDIAN_NONE 0 +#define ENDIAN_8IN16 1 +#define ENDIAN_8IN32 2 +#define ENDIAN_8IN64 3 + +static INLINE unsigned r600_endian_swap(unsigned size) +{ + if (R600_BIG_ENDIAN) { + switch (size) { + case 64: + return ENDIAN_8IN64; + case 32: + return ENDIAN_8IN32; + case 16: + return ENDIAN_8IN16; + default: + return ENDIAN_NONE; + } + } else { + return ENDIAN_NONE; + } +} #endif diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c deleted file mode 100644 index 7e131093060..00000000000 --- a/src/gallium/drivers/r600/r600_helper.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 Jerome Glisse <[email protected]> - * - * 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 - * on 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 - * THE AUTHOR(S) AND/OR THEIR 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. - * - * Authors: - * Jerome Glisse - */ -#include <stdio.h> -#include <errno.h> -#include <util/u_inlines.h> -#include "r600_pipe.h" -#include "r600d.h" - -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) -{ - switch (pprim) { - case PIPE_PRIM_POINTS: - *prim = V_008958_DI_PT_POINTLIST; - return 0; - case PIPE_PRIM_LINES: - *prim = V_008958_DI_PT_LINELIST; - return 0; - case PIPE_PRIM_LINE_STRIP: - *prim = V_008958_DI_PT_LINESTRIP; - return 0; - case PIPE_PRIM_LINE_LOOP: - *prim = V_008958_DI_PT_LINELOOP; - return 0; - case PIPE_PRIM_TRIANGLES: - *prim = V_008958_DI_PT_TRILIST; - return 0; - case PIPE_PRIM_TRIANGLE_STRIP: - *prim = V_008958_DI_PT_TRISTRIP; - return 0; - case PIPE_PRIM_TRIANGLE_FAN: - *prim = V_008958_DI_PT_TRIFAN; - return 0; - case PIPE_PRIM_POLYGON: - *prim = V_008958_DI_PT_POLYGON; - return 0; - case PIPE_PRIM_QUADS: - *prim = V_008958_DI_PT_QUADLIST; - return 0; - case PIPE_PRIM_QUAD_STRIP: - *prim = V_008958_DI_PT_QUADSTRIP; - return 0; - default: - fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); - return -EINVAL; - } -} diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 89b46f5ad7e..ec13e48e14e 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -374,27 +374,29 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; + + /* Supported except the original R600. */ case PIPE_CAP_INDEP_BLEND_ENABLE: + case PIPE_CAP_INDEP_BLEND_FUNC: /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else - return 1; + return family == CHIP_R600 ? 0 : 1; - case PIPE_CAP_TGSI_INSTANCEID: - return 0; + /* Supported on Evergreen. */ + case PIPE_CAP_SEAMLESS_CUBE_MAP: + case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: + return family >= CHIP_CEDAR ? 1 : 0; - /* Unsupported features (boolean caps). */ + /* Unsupported features. */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL: - /* R600 doesn't support per-MRT blends */ - if (family == CHIP_R600) - return 0; - else - return 0; + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: + case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: + return 0; case PIPE_CAP_ARRAY_TEXTURES: /* fix once the CS checker upstream is fixed */ @@ -409,25 +411,16 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) else return 14; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - /* FIXME allow this once infrastructure is there */ - return 16; case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - case PIPE_CAP_MAX_COMBINED_SAMPLERS: return 16; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 32; /* Render targets. */ case PIPE_CAP_MAX_RENDER_TARGETS: /* FIXME some r6xx are buggy and can only do 4 */ return 8; - /* Fragment coordinate conventions. */ - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: - return 1; - case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: - case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: - return 0; - /* Timer queries, present when the clock frequency is non zero. */ case PIPE_CAP_TIMER_QUERY: return r600_get_clock_crystal_freq(rscreen->radeon) != 0; @@ -492,9 +485,10 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e else return 16; case PIPE_SHADER_CAP_MAX_TEMPS: - return 256; //max native temporaries + return 256; /* Max native temporaries. */ case PIPE_SHADER_CAP_MAX_ADDRS: - return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ + /* FIXME Isn't this equal to TEMPS? */ + return 1; /* Max native address registers */ case PIPE_SHADER_CAP_MAX_CONSTS: return R600_MAX_CONST_BUFFER_SIZE; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 88aff0e81bb..aa5ef4efb3b 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -40,6 +40,12 @@ #define R600_MAX_CONST_BUFFERS 1 #define R600_MAX_CONST_BUFFER_SIZE 4096 +#ifdef PIPE_ARCH_BIG_ENDIAN +#define R600_BIG_ENDIAN 1 +#else +#define R600_BIG_ENDIAN 0 +#endif + enum r600_pipe_state_id { R600_PIPE_STATE_BLEND = 0, R600_PIPE_STATE_BLEND_COLOR, @@ -91,6 +97,11 @@ struct r600_pipe_blend { unsigned cb_target_mask; }; +struct r600_pipe_dsa { + struct r600_pipe_state rstate; + unsigned alpha_ref; +}; + struct r600_vertex_element { unsigned count; @@ -180,6 +191,9 @@ struct r600_pipe_context { /* shader information */ unsigned sprite_coord_enable; bool flatshade; + bool export_16bpc; + unsigned alpha_ref; + bool alpha_ref_dirty; struct r600_textures_info ps_samplers; struct r600_pipe_fences fences; @@ -241,7 +255,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, /* r600_state.c */ void r600_init_state_functions(struct r600_pipe_context *rctx); -void r600_spi_update(struct r600_pipe_context *rctx); void r600_init_config(struct r600_pipe_context *rctx); void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); @@ -253,9 +266,6 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, struct r600_resource *rbuffer, unsigned offset, unsigned stride); -/* r600_helper.h */ -int r600_conv_pipe_prim(unsigned pprim, unsigned *prim); - /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); void r600_init_surface_functions(struct r600_pipe_context *r600); @@ -281,11 +291,11 @@ void *r600_create_vertex_elements(struct pipe_context *ctx, const struct pipe_vertex_element *elements); void r600_delete_vertex_element(struct pipe_context *ctx, void *state); void r600_bind_blend_state(struct pipe_context *ctx, void *state); +void r600_bind_dsa_state(struct pipe_context *ctx, void *state); void r600_bind_rs_state(struct pipe_context *ctx, void *state); void r600_delete_rs_state(struct pipe_context *ctx, void *state); void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *state); -void r600_bind_state(struct pipe_context *ctx, void *state); void r600_delete_state(struct pipe_context *ctx, void *state); void r600_bind_vertex_elements(struct pipe_context *ctx, void *state); void *r600_create_shader_state(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 188cea0ff88..845d41ace02 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -21,6 +21,7 @@ * USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include "pipe/p_shader_tokens.h" +#include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_scan.h" #include "tgsi/tgsi_dump.h" @@ -35,12 +36,6 @@ #include <errno.h> #include <byteswap.h> -#ifdef PIPE_ARCH_BIG_ENDIAN -#define CPU_TO_LE32(x) bswap_32(x) -#else -#define CPU_TO_LE32(x) (x) -#endif - int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id) { @@ -69,8 +64,12 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s return -ENOMEM; } ptr = (uint32_t*)r600_bo_map(rctx->radeon, shader->bo, 0, NULL); - for(i = 0; i < rshader->bc.ndw; i++) { - *(ptr + i) = CPU_TO_LE32(*(rshader->bc.bytecode + i)); + if (R600_BIG_ENDIAN) { + for (i = 0; i < rshader->bc.ndw; ++i) { + ptr[i] = bswap_32(rshader->bc.bytecode[i]); + } + } else { + memcpy(ptr, rshader->bc.bytecode, rshader->bc.ndw * sizeof(*ptr)); } r600_bo_unmap(rctx->radeon, shader->bo); } @@ -477,11 +476,7 @@ static int tgsi_fetch_rel_const(struct r600_shader_ctx *ctx, unsigned int offset vtx.num_format_all = 2; /* NUM_FORMAT_SCALED */ vtx.format_comp_all = 1; /* FORMAT_COMP_SIGNED */ vtx.srf_mode_all = 1; /* SRF_MODE_NO_ZERO */ -#ifdef PIPE_ARCH_BIG_ENDIAN - vtx.endian = ENDIAN_8IN32; -#else - vtx.endian = ENDIAN_NONE; -#endif + vtx.endian = r600_endian_swap(32); if ((r = r600_bc_add_vtx(ctx->bc, &vtx))) return r; @@ -830,7 +825,8 @@ out_err: static int tgsi_unsupported(struct r600_shader_ctx *ctx) { - R600_ERR("%d tgsi opcode unsupported\n", ctx->inst_info->tgsi_opcode); + R600_ERR("%s tgsi opcode unsupported\n", + tgsi_get_opcode_name(ctx->inst_info->tgsi_opcode)); return -EINVAL; } @@ -911,6 +907,8 @@ static int tgsi_op2_s(struct r600_shader_ctx *ctx, int swap) break; case TGSI_OPCODE_ABS: alu.src[0].abs = 1; + if (alu.src[0].neg) + alu.src[0].neg = 0; break; default: break; @@ -1997,9 +1995,11 @@ static int tgsi_exp(struct r600_shader_ctx *ctx) r600_bc_src(&alu.src[0], &ctx->src[0], 0); alu.dst.sel = ctx->temp_reg; -// r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); -// if (r) -// return r; +#if 0 + r = tgsi_dst(ctx, &inst->Dst[0], i, &alu.dst); + if (r) + return r; +#endif alu.dst.write = 1; alu.dst.chan = 1; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 8646b9f4905..b9084c953ee 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -199,14 +199,17 @@ static void *r600_create_blend_state(struct pipe_context *ctx, static void *r600_create_dsa_state(struct pipe_context *ctx, const struct pipe_depth_stencil_alpha_state *state) { - struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); + struct r600_pipe_dsa *dsa = CALLOC_STRUCT(r600_pipe_dsa); unsigned db_depth_control, alpha_test_control, alpha_ref, db_shader_control; unsigned stencil_ref_mask, stencil_ref_mask_bf, db_render_override, db_render_control; + struct r600_pipe_state *rstate; - if (rstate == NULL) { + if (dsa == NULL) { return NULL; } + rstate = &dsa->rstate; + rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); @@ -246,6 +249,7 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1); alpha_ref = fui(state->alpha.ref_value); } + dsa->alpha_ref = alpha_ref; /* misc */ db_render_control = 0; @@ -262,7 +266,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028434_DB_STENCILREFMASK_BF, stencil_ref_mask_bf, 0xFFFFFFFF & C_028434_STENCILREF_BF, NULL); - r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E0_SPI_FOG_FUNC_SCALE, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); @@ -371,16 +374,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, { struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state); union util_color uc; - uint32_t coord_trunc = 0; if (rstate == NULL) { return NULL; } - if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) || - (state->min_img_filter == PIPE_TEX_FILTER_NEAREST)) - coord_trunc = 1; - rstate->id = R600_PIPE_STATE_SAMPLER; util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0, @@ -392,14 +390,11 @@ static void *r600_create_sampler_state(struct pipe_context *ctx, S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)) | S_03C000_BORDER_COLOR_TYPE(uc.ui ? V_03C000_SQ_TEX_BORDER_COLOR_REGISTER : 0), 0xFFFFFFFF, NULL); - /* FIXME LOD it depends on texture base level ... */ r600_pipe_state_add_reg(rstate, R_03C004_SQ_TEX_SAMPLER_WORD1_0, S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) | S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) | S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, - S_03C008_MC_COORD_TRUNCATE(coord_trunc) | - S_03C008_TYPE(1), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), 0xFFFFFFFF, NULL); if (uc.ui) { r600_pipe_state_add_reg(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color[0]), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color[1]), 0xFFFFFFFF, NULL); @@ -477,7 +472,6 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c depth = texture->array_size; } - /* FIXME properly handle first level != 0 */ r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0, S_038000_DIM(r600_tex_dim(texture->target)) | S_038000_TILE_MODE(array_mode) | @@ -724,7 +718,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta struct r600_surface *surf; unsigned level = state->cbufs[cb]->u.tex.level; unsigned pitch, slice; - unsigned color_info, color_info_mask; + unsigned color_info; unsigned format, swap, ntype, endian; unsigned offset; const struct util_format_description *desc; @@ -780,17 +774,36 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta S_0280A0_NUMBER_TYPE(ntype) | S_0280A0_ENDIAN(endian); - color_info_mask = 0xFFFFFFFF & ~S_0280A0_BLEND_CLAMP(1); - - /* on R600 this can't be set if BLEND_CLAMP isn't set, - if BLEND_FLOAT32 is set of > 11 bits in a UNORM or SNORM */ - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && desc->channel[i].size < 12) { - //TODO: Seems to work on RV710, but i have no idea what to do between R600-RV710 - if (rctx->family < CHIP_RV710) { - color_info |= S_0280A0_BLEND_CLAMP(1); - color_info_mask |= S_0280A0_BLEND_CLAMP(1); - } - color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + /* EXPORT_NORM is an optimzation that can be enabled for better + * performance in certain cases + */ + if (rctx->family < CHIP_RV770) { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - BLEND_CLAMP is enabled + * - BLEND_FLOAT32 is disabled + */ + // TODO get BLEND_CLAMP state from rasterizer state + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + (desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && + ntype != V_0280A0_NUMBER_SINT) && + G_0280A0_BLEND_CLAMP(color_info) && + !G_0280A0_BLEND_FLOAT32(color_info)) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); + } else { + /* EXPORT_NORM can be enabled if: + * - 11-bit or smaller UNORM/SNORM/SRGB + * - 16-bit or smaller FLOAT + */ + if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && + ((desc->channel[i].size < 12 && + desc->channel[i].type != UTIL_FORMAT_TYPE_FLOAT && + ntype != V_0280A0_NUMBER_UINT && ntype != V_0280A0_NUMBER_SINT) || + (desc->channel[i].size < 17 && + desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT))) + color_info |= S_0280A0_SOURCE_FORMAT(V_0280A0_EXPORT_NORM); } r600_pipe_state_add_reg(rstate, @@ -798,7 +811,7 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta (offset + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]); r600_pipe_state_add_reg(rstate, R_0280A0_CB_COLOR0_INFO + cb * 4, - color_info, color_info_mask, NULL); + color_info, ~S_0280A0_BLEND_CLAMP(1), NULL); r600_pipe_state_add_reg(rstate, R_028060_CB_COLOR0_SIZE + cb * 4, S_028060_PITCH_TILE_MAX(pitch) | @@ -984,7 +997,7 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.create_vertex_elements_state = r600_create_vertex_elements; rctx->context.create_vs_state = r600_create_shader_state; rctx->context.bind_blend_state = r600_bind_blend_state; - rctx->context.bind_depth_stencil_alpha_state = r600_bind_state; + rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state; rctx->context.bind_fragment_sampler_states = r600_bind_ps_sampler; rctx->context.bind_fs_state = r600_bind_ps_shader; rctx->context.bind_rasterizer_state = r600_bind_rs_state; @@ -1472,9 +1485,7 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1, rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038008_RESOURCE0_WORD2, -#ifdef PIPE_ARCH_BIG_ENDIAN - S_038008_ENDIAN_SWAP(ENDIAN_8IN32) | -#endif + S_038008_ENDIAN_SWAP(r600_endian_swap(32)) | S_038008_STRIDE(stride), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_03800C_RESOURCE0_WORD3, 0x00000000, 0xFFFFFFFF, NULL); diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 997c9a597ee..de1b811ce89 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -28,9 +28,49 @@ #include <util/u_format.h> #include <pipebuffer/pb_buffer.h> #include "pipe/p_shader_tokens.h" +#include "r600_formats.h" #include "r600_pipe.h" #include "r600d.h" +static int r600_conv_pipe_prim(unsigned pprim, unsigned *prim) +{ + switch (pprim) { + case PIPE_PRIM_POINTS: + *prim = V_008958_DI_PT_POINTLIST; + return 0; + case PIPE_PRIM_LINES: + *prim = V_008958_DI_PT_LINELIST; + return 0; + case PIPE_PRIM_LINE_STRIP: + *prim = V_008958_DI_PT_LINESTRIP; + return 0; + case PIPE_PRIM_LINE_LOOP: + *prim = V_008958_DI_PT_LINELOOP; + return 0; + case PIPE_PRIM_TRIANGLES: + *prim = V_008958_DI_PT_TRILIST; + return 0; + case PIPE_PRIM_TRIANGLE_STRIP: + *prim = V_008958_DI_PT_TRISTRIP; + return 0; + case PIPE_PRIM_TRIANGLE_FAN: + *prim = V_008958_DI_PT_TRIFAN; + return 0; + case PIPE_PRIM_POLYGON: + *prim = V_008958_DI_PT_POLYGON; + return 0; + case PIPE_PRIM_QUADS: + *prim = V_008958_DI_PT_QUADLIST; + return 0; + case PIPE_PRIM_QUAD_STRIP: + *prim = V_008958_DI_PT_QUADSTRIP; + return 0; + default: + fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim); + return -1; + } +} + /* common state between evergreen and r600 */ void r600_bind_blend_state(struct pipe_context *ctx, void *state) { @@ -46,6 +86,21 @@ void r600_bind_blend_state(struct pipe_context *ctx, void *state) r600_context_pipe_state_set(&rctx->ctx, rstate); } +void r600_bind_dsa_state(struct pipe_context *ctx, void *state) +{ + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; + struct r600_pipe_dsa *dsa = state; + struct r600_pipe_state *rstate; + + if (state == NULL) + return; + rstate = &dsa->rstate; + rctx->states[rstate->id] = rstate; + rctx->alpha_ref = dsa->alpha_ref; + rctx->alpha_ref_dirty = true; + r600_context_pipe_state_set(&rctx->ctx, rstate); +} + void r600_bind_rs_state(struct pipe_context *ctx, void *state) { struct r600_pipe_rasterizer *rs = (struct r600_pipe_rasterizer *)state; @@ -91,17 +146,6 @@ void r600_sampler_view_destroy(struct pipe_context *ctx, FREE(resource); } -void r600_bind_state(struct pipe_context *ctx, void *state) -{ - struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; - struct r600_pipe_state *rstate = (struct r600_pipe_state *)state; - - if (state == NULL) - return; - rctx->states[rstate->id] = rstate; - r600_context_pipe_state_set(&rctx->ctx, rstate); -} - void r600_delete_state(struct pipe_context *ctx, void *state) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -276,8 +320,25 @@ void r600_delete_vs_shader(struct pipe_context *ctx, void *state) free(shader); } +static void r600_update_alpha_ref(struct r600_pipe_context *rctx) +{ + unsigned alpha_ref = rctx->alpha_ref; + struct r600_pipe_state rstate; + + if (!rctx->alpha_ref_dirty) + return; + + rstate.nregs = 0; + if (rctx->export_16bpc) + alpha_ref &= ~0x1FFF; + r600_pipe_state_add_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); + rctx->alpha_ref_dirty = false; +} + /* FIXME optimize away spi update when it's not needed */ -void r600_spi_update(struct r600_pipe_context *rctx) +static void r600_spi_update(struct r600_pipe_context *rctx, unsigned prim) { struct r600_pipe_shader *shader = rctx->ps_shader; struct r600_pipe_state rstate; @@ -309,6 +370,12 @@ void r600_spi_update(struct r600_pipe_context *rctx) r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + i * 4, tmp, 0xFFFFFFFF, NULL); } + + if (prim == PIPE_PRIM_QUADS || prim == PIPE_PRIM_QUAD_STRIP || prim == PIPE_PRIM_POLYGON) { + r600_pipe_state_add_reg(&rstate, R_028814_PA_SU_SC_MODE_CNTL, + S_028814_PROVOKING_VTX_LAST(1), + S_028814_PROVOKING_VTX_LAST(1), NULL); + } r600_context_pipe_state_set(&rctx->ctx, &rstate); } @@ -472,16 +539,16 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) case 2: vgt_draw_initiator = 0; vgt_dma_index_type = 0; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN16; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN16; + } break; case 4: vgt_draw_initiator = 0; vgt_dma_index_type = 1; -#ifdef PIPE_ARCH_BIG_ENDIAN - vgt_dma_swap_mode = ENDIAN_8IN32; -#endif + if (R600_BIG_ENDIAN) { + vgt_dma_swap_mode = ENDIAN_8IN32; + } break; case 0: vgt_draw_initiator = 2; @@ -508,7 +575,8 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) return; } - r600_spi_update(rctx); + r600_update_alpha_ref(rctx); + r600_spi_update(rctx, draw.info.mode); mask = 0; for (int i = 0; i < rctx->framebuffer.nr_cbufs; i++) { diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 5eabfdc2bc6..39c647835a6 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -343,7 +343,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_A8B8G8R8_UNORM: case PIPE_FORMAT_X8B8G8R8_UNORM: - // case PIPE_FORMAT_R8SG8SB8UX8U_NORM: + /* case PIPE_FORMAT_R8SG8SB8UX8U_NORM: */ return V_0280A0_SWAP_STD_REV; case PIPE_FORMAT_Z24X8_UNORM: @@ -362,6 +362,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format) case PIPE_FORMAT_B10G10R10A2_UNORM: return V_0280A0_SWAP_ALT; + case PIPE_FORMAT_R11G11B10_FLOAT: case PIPE_FORMAT_R16G16_UNORM: case PIPE_FORMAT_R16G16_FLOAT: case PIPE_FORMAT_R32_FLOAT: @@ -465,6 +466,8 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_R16G16_UNORM: return V_0280A0_COLOR_16_16; + case PIPE_FORMAT_R11G11B10_FLOAT: + return V_0280A0_COLOR_10_11_11_FLOAT; /* 64-bit buffers. */ case PIPE_FORMAT_R16G16B16_USCALED: @@ -499,60 +502,60 @@ 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. */ } } static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat) { -#ifdef PIPE_ARCH_BIG_ENDIAN - switch(colorformat) { - case V_0280A0_COLOR_4_4: - return(ENDIAN_NONE); - - /* 8-bit buffers. */ - case V_0280A0_COLOR_8: - return(ENDIAN_NONE); - - /* 16-bit buffers. */ - case V_0280A0_COLOR_5_6_5: - case V_0280A0_COLOR_1_5_5_5: - case V_0280A0_COLOR_4_4_4_4: - case V_0280A0_COLOR_16: - case V_0280A0_COLOR_8_8: - return(ENDIAN_8IN16); - - /* 32-bit buffers. */ - case V_0280A0_COLOR_8_8_8_8: - case V_0280A0_COLOR_2_10_10_10: - case V_0280A0_COLOR_8_24: - case V_0280A0_COLOR_24_8: - case V_0280A0_COLOR_32_FLOAT: - case V_0280A0_COLOR_16_16_FLOAT: - case V_0280A0_COLOR_16_16: - return(ENDIAN_8IN32); - - /* 64-bit buffers. */ - case V_0280A0_COLOR_16_16_16_16: - case V_0280A0_COLOR_16_16_16_16_FLOAT: - return(ENDIAN_8IN16); - - case V_0280A0_COLOR_32_32_FLOAT: - case V_0280A0_COLOR_32_32: - return(ENDIAN_8IN32); - - /* 128-bit buffers. */ - case V_0280A0_COLOR_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32_FLOAT: - case V_0280A0_COLOR_32_32_32_32: - return(ENDIAN_8IN32); - default: - return ENDIAN_NONE; /* Unsupported. */ + if (R600_BIG_ENDIAN) { + switch(colorformat) { + case V_0280A0_COLOR_4_4: + return(ENDIAN_NONE); + + /* 8-bit buffers. */ + case V_0280A0_COLOR_8: + return(ENDIAN_NONE); + + /* 16-bit buffers. */ + case V_0280A0_COLOR_5_6_5: + case V_0280A0_COLOR_1_5_5_5: + case V_0280A0_COLOR_4_4_4_4: + case V_0280A0_COLOR_16: + case V_0280A0_COLOR_8_8: + return(ENDIAN_8IN16); + + /* 32-bit buffers. */ + case V_0280A0_COLOR_8_8_8_8: + case V_0280A0_COLOR_2_10_10_10: + case V_0280A0_COLOR_8_24: + case V_0280A0_COLOR_24_8: + case V_0280A0_COLOR_32_FLOAT: + case V_0280A0_COLOR_16_16_FLOAT: + case V_0280A0_COLOR_16_16: + return(ENDIAN_8IN32); + + /* 64-bit buffers. */ + case V_0280A0_COLOR_16_16_16_16: + case V_0280A0_COLOR_16_16_16_16_FLOAT: + return(ENDIAN_8IN16); + + case V_0280A0_COLOR_32_32_FLOAT: + case V_0280A0_COLOR_32_32: + return(ENDIAN_8IN32); + + /* 128-bit buffers. */ + case V_0280A0_COLOR_32_32_32_FLOAT: + case V_0280A0_COLOR_32_32_32_32_FLOAT: + case V_0280A0_COLOR_32_32_32_32: + return(ENDIAN_8IN32); + default: + return ENDIAN_NONE; /* Unsupported. */ + } + } else { + return ENDIAN_NONE; } -#else - return ENDIAN_NONE; -#endif } static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 690aeafcc52..77cdd8dc33d 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -892,13 +892,17 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, switch (format) { case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_SNORM: word4 |= sign_bit[0]; case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_LATC1_UNORM: result = FMT_BC4; goto out_word4; case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: word4 |= sign_bit[0] | sign_bit[1]; case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: result = FMT_BC5; goto out_word4; default: @@ -935,6 +939,14 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen, } } + if (format == PIPE_FORMAT_R9G9B9E5_FLOAT) { + result = FMT_5_9_9_9_SHAREDEXP; + goto out_word4; + } else if (format == PIPE_FORMAT_R11G11B10_FLOAT) { + result = FMT_10_11_11_FLOAT; + goto out_word4; + } + for (i = 0; i < desc->nr_channels; i++) { if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { @@ -1088,6 +1100,6 @@ out_word4: *yuv_format_p = yuv_format; return result; out_unknown: -// R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); + /* R600_ERR("Unable to handle texformat %d %s\n", format, util_format_name(format)); */ return ~0; } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 2bff52bec8c..8296b52eb94 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -3461,9 +3461,4 @@ #define SQ_TEX_INST_SAMPLE_L 0x11 #define SQ_TEX_INST_SAMPLE_C 0x18 -#define ENDIAN_NONE 0 -#define ENDIAN_8IN16 1 -#define ENDIAN_8IN32 2 -#define ENDIAN_8IN64 3 - #endif diff --git a/src/gallium/drivers/svga/svga_pipe_clear.c b/src/gallium/drivers/svga/svga_pipe_clear.c index b288c3eb2a6..2bba77769ad 100644 --- a/src/gallium/drivers/svga/svga_pipe_clear.c +++ b/src/gallium/drivers/svga/svga_pipe_clear.c @@ -46,7 +46,7 @@ try_clear(struct svga_context *svga, boolean restore_viewport = FALSE; SVGA3dClearFlag flags = 0; struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; - union util_color uc; + union util_color uc = {0}; ret = svga_update_state(svga, SVGA_STATE_HW_CLEAR); if (ret) diff --git a/src/gallium/drivers/svga/svga_state_framebuffer.c b/src/gallium/drivers/svga/svga_state_framebuffer.c index cc4819431ad..502f21fc42c 100644 --- a/src/gallium/drivers/svga/svga_state_framebuffer.c +++ b/src/gallium/drivers/svga/svga_state_framebuffer.c @@ -474,9 +474,26 @@ static int emit_clip_planes( struct svga_context *svga, /* TODO: just emit directly from svga_set_clip_state()? */ for (i = 0; i < svga->curr.clip.nr; i++) { - ret = SVGA3D_SetClipPlane( svga->swc, - i, - svga->curr.clip.ucp[i] ); + /* need to express the plane in D3D-style coordinate space. + * GL coords get converted to D3D coords with the matrix: + * [ 1 0 0 0 ] + * [ 0 -1 0 0 ] + * [ 0 0 2 0 ] + * [ 0 0 -1 1 ] + * Apply that matrix to our plane equation, and invert Y. + */ + float a = svga->curr.clip.ucp[i][0]; + float b = svga->curr.clip.ucp[i][1]; + float c = svga->curr.clip.ucp[i][2]; + float d = svga->curr.clip.ucp[i][3]; + float plane[4]; + + plane[0] = a; + plane[1] = b; + plane[2] = 2.0f * c; + plane[3] = d - c; + + ret = SVGA3D_SetClipPlane(svga->swc, i, plane); if(ret != PIPE_OK) return ret; } diff --git a/src/gallium/drivers/svga/svga_state_need_swtnl.c b/src/gallium/drivers/svga/svga_state_need_swtnl.c index 68c02578789..5a37f9fc287 100644 --- a/src/gallium/drivers/svga/svga_state_need_swtnl.c +++ b/src/gallium/drivers/svga/svga_state_need_swtnl.c @@ -139,13 +139,6 @@ static int update_need_pipeline( struct svga_context *svga, need_pipeline = TRUE; } - /* SVGA_NEW_CLIP - */ - if (svga->curr.clip.nr) { - SVGA_DBG(DEBUG_SWTNL, "%s: userclip\n", __FUNCTION__); - need_pipeline = TRUE; - } - if (need_pipeline != svga->state.sw.need_pipeline) { svga->state.sw.need_pipeline = need_pipeline; svga->dirty |= SVGA_NEW_NEED_PIPELINE; @@ -163,7 +156,6 @@ struct svga_tracked_state svga_update_need_pipeline = { "need pipeline", (SVGA_NEW_RAST | - SVGA_NEW_CLIP | SVGA_NEW_VS | SVGA_NEW_REDUCED_PRIMITIVE), update_need_pipeline diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index ab13f3fdf19..28f32793742 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -240,6 +240,11 @@ static int emit_rss( struct svga_context *svga, EMIT_RS_FLOAT( svga, bias, DEPTHBIAS, fail ); } + if (dirty & SVGA_NEW_CLIP) { + /* the number of clip planes is how many planes to enable */ + unsigned enabled = (1 << svga->curr.clip.nr) - 1; + EMIT_RS( svga, enabled, CLIPPLANEENABLE, fail ); + } if (queue.rs_count) { SVGA3dRenderState *rs; @@ -276,6 +281,7 @@ struct svga_tracked_state svga_hw_rss = (SVGA_NEW_BLEND | SVGA_NEW_BLEND_COLOR | + SVGA_NEW_CLIP | SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_STENCIL_REF | SVGA_NEW_RAST | |