diff options
author | Jerome Glisse <[email protected]> | 2010-07-27 20:15:17 -0400 |
---|---|---|
committer | Jerome Glisse <[email protected]> | 2010-07-27 20:18:32 -0400 |
commit | 641c9adb09e8707f659d42be600d16902ebf8895 (patch) | |
tree | db9200b3266bbc931c2b2636ca31fe5c158b80a5 /src/gallium | |
parent | 25472942c9640f6c0d252de2f013d04ac2355b1d (diff) |
r600g: texture support
Add texture mapping support, redbook/texbind works if
you comment out glClear and second checkboard. Need to
fix :
- texture overwritting
- lod & mip/map handling
- unormalized coordinate handling
- texture view with first leve > 0
- and many other things
Signed-off-by: Jerome Glisse <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/r600/r600_context.c | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_context.h | 12 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_draw.c | 11 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_shader.c | 78 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 277 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_texture.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600d.h | 235 |
7 files changed, 610 insertions, 9 deletions
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c index 05575b57676..3c5195f79e4 100644 --- a/src/gallium/drivers/r600/r600_context.c +++ b/src/gallium/drivers/r600/r600_context.c @@ -55,7 +55,7 @@ static void r600_flush(struct pipe_context *ctx, unsigned flags, */ if (!dc) radeon_ctx_dump_bof(rctx->ctx, "gallium.bof"); -#if 0 +#if 1 radeon_ctx_submit(rctx->ctx); #endif rctx->ctx = radeon_ctx_decref(rctx->ctx); diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h index 669aaec0b24..30f33f757ec 100644 --- a/src/gallium/drivers/r600/r600_context.h +++ b/src/gallium/drivers/r600/r600_context.h @@ -23,6 +23,7 @@ #ifndef R600_CONTEXT_H #define R600_CONTEXT_H +#include <stdio.h> #include <pipe/p_state.h> #include <pipe/p_context.h> #include <tgsi/tgsi_scan.h> @@ -45,6 +46,11 @@ struct r600_pipe_shader { struct radeon_state *state; }; +struct r600_texture_resource { + struct pipe_sampler_view view; + struct radeon_state *state; +}; + struct r600_context { struct pipe_context context; struct r600_screen *screen; @@ -55,6 +61,12 @@ struct r600_context { struct radeon_state *config; struct r600_pipe_shader *ps_shader; struct r600_pipe_shader *vs_shader; + unsigned nps_sampler; + struct radeon_state *ps_sampler[PIPE_MAX_ATTRIBS]; + unsigned nps_view; + unsigned nvs_view; + struct r600_texture_resource *ps_view[PIPE_MAX_ATTRIBS]; + struct r600_texture_resource *vs_view[PIPE_MAX_ATTRIBS]; unsigned flat_shade; unsigned nvertex_buffer; struct r600_vertex_elements_state *vertex_elements; diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c index 724fb6c988e..e0d624889f1 100644 --- a/src/gallium/drivers/r600/r600_draw.c +++ b/src/gallium/drivers/r600/r600_draw.c @@ -125,6 +125,17 @@ static int r600_draw_common(struct r600_draw *draw) if (r) return r; } + /* setup texture sampler & resource */ + for (i = 0 ; i < rctx->nps_sampler; i++) { + r = radeon_draw_set_new(rctx->draw, rctx->ps_sampler[i]); + if (r) + return r; + } + for (i = 0 ; i < rctx->nps_view; i++) { + r = radeon_draw_set_new(rctx->draw, rctx->ps_view[i]->state); + if (r) + return r; + } /* FIXME start need to change winsys */ draw->draw = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW); if (draw->draw == NULL) diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 17e9c14d6b2..9796112775d 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -838,12 +838,82 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; struct r600_bc_tex tex; + struct r600_bc_alu alu; + unsigned src_gpr; + int r; + + src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; + + /* Add perspective divide */ + if (ctx->inst_info->tgsi_opcode == TGSI_OPCODE_TXP) { + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE; + alu.src[0].sel = src_gpr; + alu.src[0].chan = 3; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = 0; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 0; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = 1; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL; + alu.src[0].sel = ctx->temp_reg; + alu.src[0].chan = 3; + alu.src[1].sel = src_gpr; + alu.src[1].chan = 2; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 2; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + memset(&alu, 0, sizeof(struct r600_bc_alu)); + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV; + alu.src[0].sel = 249; + alu.src[0].chan = 0; + alu.dst.sel = ctx->temp_reg; + alu.dst.chan = 3; + alu.last = 1; + alu.dst.write = 1; + r = r600_bc_add_alu(ctx->bc, &alu); + if (r) + return r; + src_gpr = ctx->temp_reg; + } + /* TODO use temp if src_gpr is not a temporary reg (File != TEMPORARY) */ memset(&tex, 0, sizeof(struct r600_bc_tex)); tex.inst = ctx->inst_info->r600_opcode; tex.resource_id = ctx->file_offset[inst->Src[1].Register.File] + inst->Src[1].Register.Index; tex.sampler_id = tex.resource_id; - tex.src_gpr = ctx->file_offset[inst->Src[0].Register.File] + inst->Src[0].Register.Index; + tex.src_gpr = src_gpr; tex.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Src[0].Register.Index; tex.dst_sel_x = 0; tex.dst_sel_y = 1; @@ -853,6 +923,10 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) tex.src_sel_y = 1; tex.src_sel_z = 2; tex.src_sel_w = 3; + tex.coord_type_x = 1; + tex.coord_type_y = 1; + tex.coord_type_z = 1; + tex.coord_type_w = 1; return r600_bc_add_tex(ctx->bc, &tex); } @@ -912,7 +986,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_SLE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_SNE, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_STR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_TEX, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_TEX, 0, 0x10, tgsi_tex}, {TGSI_OPCODE_TXD, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_TXP, 0, 0x10, tgsi_tex}, {TGSI_OPCODE_UP2H, 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 84a13e4ef7a..6503c3740e8 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -187,6 +187,8 @@ static void *r600_create_rs_state(struct pipe_context *ctx, struct radeon_state *rstate; rctx->flat_shade = state->flatshade; + rctx->flat_shade = 0; +R600_ERR("flat shade with texture broke tex coord interp\n"); rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER); if (rstate == NULL) return NULL; @@ -224,43 +226,306 @@ static void r600_bind_rs_state(struct pipe_context *ctx, void *state) radeon_draw_set(rctx->draw, state); } +static inline unsigned r600_tex_wrap(unsigned wrap) +{ + switch (wrap) { + default: + case PIPE_TEX_WRAP_REPEAT: + return V_03C000_SQ_TEX_WRAP; + case PIPE_TEX_WRAP_CLAMP: + return V_03C000_SQ_TEX_CLAMP_LAST_TEXEL; + case PIPE_TEX_WRAP_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_CLAMP_HALF_BORDER; + case PIPE_TEX_WRAP_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_CLAMP_BORDER; + case PIPE_TEX_WRAP_MIRROR_REPEAT: + return V_03C000_SQ_TEX_MIRROR; + case PIPE_TEX_WRAP_MIRROR_CLAMP: + return V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: + return V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER; + case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: + return V_03C000_SQ_TEX_MIRROR_ONCE_BORDER; + } +} + +static inline unsigned r600_tex_filter(unsigned filter) +{ + switch (filter) { + default: + case PIPE_TEX_FILTER_NEAREST: + return V_03C000_SQ_TEX_XY_FILTER_POINT; + case PIPE_TEX_FILTER_LINEAR: + return V_03C000_SQ_TEX_XY_FILTER_BILINEAR; + } +} + +static inline unsigned r600_tex_mipfilter(unsigned filter) +{ + switch (filter) { + case PIPE_TEX_MIPFILTER_NEAREST: + return V_03C000_SQ_TEX_Z_FILTER_POINT; + case PIPE_TEX_MIPFILTER_LINEAR: + return V_03C000_SQ_TEX_Z_FILTER_LINEAR; + default: + case PIPE_TEX_MIPFILTER_NONE: + return V_03C000_SQ_TEX_Z_FILTER_NONE; + } +} + +static inline unsigned r600_tex_compare(unsigned compare) +{ + switch (compare) { + default: + case PIPE_FUNC_NEVER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER; + case PIPE_FUNC_LESS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESS; + case PIPE_FUNC_EQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL; + case PIPE_FUNC_LEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL; + case PIPE_FUNC_GREATER: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER; + case PIPE_FUNC_NOTEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL; + case PIPE_FUNC_GEQUAL: + return V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL; + case PIPE_FUNC_ALWAYS: + return V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS; + } +} + static void *r600_create_sampler_state(struct pipe_context *ctx, const struct pipe_sampler_state *state) { - return NULL; + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct radeon_state *rstate; + + rstate = radeon_state(rscreen->rw, R600_PS_SAMPLER_TYPE, R600_PS_SAMPLER); + if (rstate == NULL) + return NULL; + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0] = + S_03C000_CLAMP_X(r600_tex_wrap(state->wrap_s)) | + S_03C000_CLAMP_Y(r600_tex_wrap(state->wrap_t)) | + S_03C000_CLAMP_Z(r600_tex_wrap(state->wrap_r)) | + S_03C000_XY_MAG_FILTER(r600_tex_filter(state->mag_img_filter)) | + S_03C000_XY_MIN_FILTER(r600_tex_filter(state->min_img_filter)) | + S_03C000_MIP_FILTER(r600_tex_mipfilter(state->min_mip_filter)) | + S_03C000_DEPTH_COMPARE_FUNCTION(r600_tex_compare(state->compare_func)); + /* FIXME LOD it depends on texture base level ... */ + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0] = + S_03C004_MIN_LOD(0) | + S_03C004_MAX_LOD(0) | + S_03C004_LOD_BIAS(0); + rstate->states[R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0] = S_03C008_TYPE(1); + if (radeon_state_pm4(rstate)) { + radeon_state_decref(rstate); + return NULL; + } + return rstate; } static void r600_bind_sampler_states(struct pipe_context *ctx, unsigned count, void **states) { + struct r600_context *rctx = r600_context(ctx); + unsigned i; + + /* FIXME split VS/PS/GS sampler */ + for (i = 0; i < count; i++) { + rctx->ps_sampler[i] = radeon_state_decref(rctx->ps_sampler[i]); + } + rctx->nps_sampler = count; + for (i = 0; i < count; i++) { + rctx->ps_sampler[i] = radeon_state_incref(states[i]); + rctx->ps_sampler[i]->id = R600_PS_SAMPLER + i; + } +} + +static inline unsigned r600_tex_swizzle(unsigned swizzle) +{ + switch (swizzle) { + case PIPE_SWIZZLE_RED: + return V_038010_SQ_SEL_X; + case PIPE_SWIZZLE_GREEN: + return V_038010_SQ_SEL_Y; + case PIPE_SWIZZLE_BLUE: + return V_038010_SQ_SEL_Z; + case PIPE_SWIZZLE_ALPHA: + return V_038010_SQ_SEL_W; + case PIPE_SWIZZLE_ZERO: + return V_038010_SQ_SEL_0; + default: + case PIPE_SWIZZLE_ONE: + return V_038010_SQ_SEL_1; + } +} + +static inline unsigned r600_format_type(unsigned format_type) +{ + switch (format_type) { + default: + case UTIL_FORMAT_TYPE_UNSIGNED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED; + case UTIL_FORMAT_TYPE_SIGNED: + return V_038010_SQ_FORMAT_COMP_SIGNED; + case UTIL_FORMAT_TYPE_FIXED: + return V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED; + } +} + +static inline unsigned r600_tex_dim(unsigned dim) +{ + switch (dim) { + default: + case PIPE_TEXTURE_1D: + return V_038000_SQ_TEX_DIM_1D; + case PIPE_TEXTURE_2D: + return V_038000_SQ_TEX_DIM_2D; + case PIPE_TEXTURE_3D: + return V_038000_SQ_TEX_DIM_3D; + case PIPE_TEXTURE_CUBE: + return V_038000_SQ_TEX_DIM_CUBEMAP; + } } static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx, struct pipe_resource *texture, - const struct pipe_sampler_view *templ) + const struct pipe_sampler_view *view) { - struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); + struct r600_screen *rscreen = r600_screen(ctx->screen); + struct r600_texture_resource *rtexture; + const struct util_format_description *desc; + struct r600_texture *tmp; + struct r600_buffer *rbuffer; + unsigned format; - *view = *templ; - return view; + if (r600_conv_pipe_format(texture->format, &format)) + return NULL; + rtexture = CALLOC_STRUCT(r600_texture_resource); + if (rtexture == NULL) + return NULL; + desc = util_format_description(texture->format); + assert(desc == NULL); + rtexture->state = radeon_state(rscreen->rw, R600_PS_RESOURCE_TYPE, R600_PS_RESOURCE); + if (rtexture->state == NULL) { + FREE(rtexture); + return NULL; + } + rtexture->view = *view; + rtexture->view.reference.count = 1; + rtexture->view.texture = NULL; + pipe_resource_reference(&rtexture->view.texture, texture); + rtexture->view.context = ctx; + + tmp = (struct r600_texture*)texture; + rbuffer = (struct r600_buffer*)tmp->buffer; + rtexture->state->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rtexture->state->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo); + rtexture->state->nbo = 2; + rtexture->state->placement[0] = RADEON_GEM_DOMAIN_GTT; + rtexture->state->placement[1] = RADEON_GEM_DOMAIN_GTT; + rtexture->state->placement[2] = RADEON_GEM_DOMAIN_GTT; + rtexture->state->placement[3] = RADEON_GEM_DOMAIN_GTT; + + /* FIXME properly handle first level != 0 */ + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = + S_038000_DIM(r600_tex_dim(texture->target)) | + S_038000_PITCH((tmp->pitch[0] / 8) - 1) | + S_038000_TEX_WIDTH(texture->width0 - 1); + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = + S_038004_TEX_HEIGHT(texture->height0 - 1) | + S_038004_TEX_DEPTH(texture->depth0 - 1) | + S_038004_DATA_FORMAT(format); + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = 0; + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = tmp->offset[1] >> 8; + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = + S_038010_FORMAT_COMP_X(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_Y(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_Z(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_FORMAT_COMP_W(r600_format_type(UTIL_FORMAT_TYPE_UNSIGNED)) | + S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) | + S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) | + S_038010_REQUEST_SIZE(1) | + S_038010_DST_SEL_X(r600_tex_swizzle(view->swizzle_r)) | + S_038010_DST_SEL_Y(r600_tex_swizzle(view->swizzle_g)) | + S_038010_DST_SEL_Z(r600_tex_swizzle(view->swizzle_b)) | + S_038010_DST_SEL_W(r600_tex_swizzle(view->swizzle_a)) | + S_038010_BASE_LEVEL(view->first_level); + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = + S_038014_LAST_LEVEL(view->last_level) | + S_038014_BASE_ARRAY(0) | + S_038014_LAST_ARRAY(0); + rtexture->state->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = + S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_TEXTURE); + return &rtexture->view; } static void r600_sampler_view_destroy(struct pipe_context *ctx, struct pipe_sampler_view *view) { - FREE(view); + struct r600_texture_resource *texture; + + if (view == NULL) + return; + texture = LIST_ENTRY(struct r600_texture_resource, view, view); + radeon_state_decref(texture->state); + FREE(texture); } static void r600_set_fragment_sampler_views(struct pipe_context *ctx, unsigned count, struct pipe_sampler_view **views) { + struct r600_texture_resource *rtexture; + struct r600_context *rctx = r600_context(ctx); + struct pipe_sampler_view *tmp; + unsigned i; + + if (views == NULL) + return; + + for (i = 0; i < rctx->nps_view; i++) { + tmp = &rctx->ps_view[i]->view; + pipe_sampler_view_reference(&tmp, NULL); + rctx->ps_view[i] = NULL; + } + rctx->nps_view = count; + for (i = 0; i < count; i++) { + rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view); + rctx->ps_view[i] = rtexture; + tmp = NULL; + pipe_sampler_view_reference(&tmp, views[i]); + rtexture->state->id = R600_PS_RESOURCE + i; + } } static void r600_set_vertex_sampler_views(struct pipe_context *ctx, unsigned count, struct pipe_sampler_view **views) { + struct r600_texture_resource *rtexture; + struct r600_context *rctx = r600_context(ctx); + struct pipe_sampler_view *tmp; + unsigned i; + + if (views == NULL) + return; + + for (i = 0; i < rctx->nvs_view; i++) { + tmp = &rctx->vs_view[i]->view; + pipe_sampler_view_reference(&tmp, NULL); + rctx->vs_view[i] = NULL; + } + rctx->nps_view = count; + for (i = 0; i < count; i++) { + rtexture = LIST_ENTRY(struct r600_texture_resource, views[i], view); + rctx->vs_view[i] = rtexture; + tmp = NULL; + pipe_sampler_view_reference(&tmp, views[i]); + rtexture->state->id = R600_VS_RESOURCE + i; + } } static void r600_set_scissor_state(struct pipe_context *ctx, diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 903cfad80a8..1c219a55799 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,7 +31,9 @@ #include <util/u_memory.h> #include "state_tracker/drm_driver.h" #include "r600_screen.h" +#include "r600_context.h" #include "r600_texture.h" +#include "r600d.h" extern struct u_resource_vtbl r600_texture_vtbl; @@ -69,6 +71,8 @@ static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture rtex->offset[i] = offset; rtex->layer_size[i] = layer_size; rtex->pitch[i] = stride / util_format_get_blocksize(ptex->format); + rtex->pitch[i] += R600_TEXEL_PITCH_ALIGNMENT_MASK; + rtex->pitch[i] &= ~R600_TEXEL_PITCH_ALIGNMENT_MASK; rtex->stride[i] = stride; offset += align(size, 32); } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index 44834984c68..593b95c9c71 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -26,6 +26,8 @@ #ifndef R600D_H #define R600D_H +#define R600_TEXEL_PITCH_ALIGNMENT_MASK 0x7 + #define PKT3_NOP 0x10 #define PKT3_INDIRECT_BUFFER_END 0x17 #define PKT3_SET_PREDICATION 0x20 @@ -574,6 +576,132 @@ #define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6) #define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1) #define C_0287F0_USE_OPAQUE 0xFFFFFFBF +#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000 +#define S_038000_DIM(x) (((x) & 0x7) << 0) +#define G_038000_DIM(x) (((x) >> 0) & 0x7) +#define C_038000_DIM 0xFFFFFFF8 +#define V_038000_SQ_TEX_DIM_1D 0x00000000 +#define V_038000_SQ_TEX_DIM_2D 0x00000001 +#define V_038000_SQ_TEX_DIM_3D 0x00000002 +#define V_038000_SQ_TEX_DIM_CUBEMAP 0x00000003 +#define V_038000_SQ_TEX_DIM_1D_ARRAY 0x00000004 +#define V_038000_SQ_TEX_DIM_2D_ARRAY 0x00000005 +#define V_038000_SQ_TEX_DIM_2D_MSAA 0x00000006 +#define V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 +#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3) +#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF) +#define C_038000_TILE_MODE 0xFFFFFF87 +#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7) +#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1) +#define C_038000_TILE_TYPE 0xFFFFFF7F +#define S_038000_PITCH(x) (((x) & 0x7FF) << 8) +#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF) +#define C_038000_PITCH 0xFFF800FF +#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19) +#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF) +#define C_038000_TEX_WIDTH 0x0007FFFF +#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004 +#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0) +#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF) +#define C_038004_TEX_HEIGHT 0xFFFFE000 +#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13) +#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF) +#define C_038004_TEX_DEPTH 0xFC001FFF +#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26) +#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F) +#define C_038004_DATA_FORMAT 0x03FFFFFF +#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008 +#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_038008_BASE_ADDRESS 0x00000000 +#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C +#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) +#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) +#define C_03800C_MIP_ADDRESS 0x00000000 +#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010 +#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) +#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) +#define C_038010_FORMAT_COMP_X 0xFFFFFFFC +#define V_038010_SQ_FORMAT_COMP_UNSIGNED 0x00000000 +#define V_038010_SQ_FORMAT_COMP_SIGNED 0x00000001 +#define V_038010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002 +#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) +#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) +#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3 +#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) +#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) +#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF +#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) +#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) +#define C_038010_FORMAT_COMP_W 0xFFFFFF3F +#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) +#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) +#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF +#define V_038010_SQ_NUM_FORMAT_NORM 0x00000000 +#define V_038010_SQ_NUM_FORMAT_INT 0x00000001 +#define V_038010_SQ_NUM_FORMAT_SCALED 0x00000002 +#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) +#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) +#define C_038010_SRF_MODE_ALL 0xFFFFFBFF +#define V_038010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_038010_SFR_MODE_NO_ZERO 0x00000001 +#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) +#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) +#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF +#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) +#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) +#define C_038010_ENDIAN_SWAP 0xFFFFCFFF +#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14) +#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3) +#define C_038010_REQUEST_SIZE 0xFFFF3FFF +#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16) +#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7) +#define C_038010_DST_SEL_X 0xFFF8FFFF +#define V_038010_SQ_SEL_X 0x00000000 +#define V_038010_SQ_SEL_Y 0x00000001 +#define V_038010_SQ_SEL_Z 0x00000002 +#define V_038010_SQ_SEL_W 0x00000003 +#define V_038010_SQ_SEL_0 0x00000004 +#define V_038010_SQ_SEL_1 0x00000005 +#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19) +#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7) +#define C_038010_DST_SEL_Y 0xFFC7FFFF +#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22) +#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7) +#define C_038010_DST_SEL_Z 0xFE3FFFFF +#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25) +#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7) +#define C_038010_DST_SEL_W 0xF1FFFFFF +#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28) +#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF) +#define C_038010_BASE_LEVEL 0x0FFFFFFF +#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014 +#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0) +#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF) +#define C_038014_LAST_LEVEL 0xFFFFFFF0 +#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) +#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) +#define C_038014_BASE_ARRAY 0xFFFE000F +#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) +#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) +#define C_038014_LAST_ARRAY 0xC001FFFF +#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018 +#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0) +#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3) +#define C_038018_MPEG_CLAMP 0xFFFFFFFC +#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5) +#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7) +#define C_038018_PERF_MODULATION 0xFFFFFF1F +#define S_038018_INTERLACED(x) (((x) & 0x1) << 8) +#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1) +#define C_038018_INTERLACED 0xFFFFFEFF +#define S_038018_TYPE(x) (((x) & 0x3) << 30) +#define G_038018_TYPE(x) (((x) >> 30) & 0x3) +#define C_038018_TYPE 0x3FFFFFFF +#define V_038010_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000 +#define V_038010_SQ_TEX_VTX_INVALID_BUFFER 0x00000001 +#define V_038010_SQ_TEX_VTX_VALID_TEXTURE 0x00000002 +#define V_038010_SQ_TEX_VTX_VALID_BUFFER 0x00000003 #define R_038008_SQ_VTX_CONSTANT_WORD2_0 0x038008 #define S_038008_BASE_ADDRESS_HI(x) (((x) & 0xFF) << 0) #define G_038008_BASE_ADDRESS_HI(x) (((x) >> 0) & 0xFF) @@ -633,6 +761,113 @@ #define S_038008_ENDIAN_SWAP(x) (((x) & 0x3) << 30) #define G_038008_ENDIAN_SWAP(x) (((x) >> 30) & 0x3) #define C_038008_ENDIAN_SWAP 0x3FFFFFFF +#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000 +#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0) +#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7) +#define C_03C000_CLAMP_X 0xFFFFFFF8 +#define V_03C000_SQ_TEX_WRAP 0x00000000 +#define V_03C000_SQ_TEX_MIRROR 0x00000001 +#define V_03C000_SQ_TEX_CLAMP_LAST_TEXEL 0x00000002 +#define V_03C000_SQ_TEX_MIRROR_ONCE_LAST_TEXEL 0x00000003 +#define V_03C000_SQ_TEX_CLAMP_HALF_BORDER 0x00000004 +#define V_03C000_SQ_TEX_MIRROR_ONCE_HALF_BORDER 0x00000005 +#define V_03C000_SQ_TEX_CLAMP_BORDER 0x00000006 +#define V_03C000_SQ_TEX_MIRROR_ONCE_BORDER 0x00000007 +#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3) +#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7) +#define C_03C000_CLAMP_Y 0xFFFFFFC7 +#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6) +#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7) +#define C_03C000_CLAMP_Z 0xFFFFFE3F +#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9) +#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7) +#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF +#define V_03C000_SQ_TEX_XY_FILTER_POINT 0x00000000 +#define V_03C000_SQ_TEX_XY_FILTER_BILINEAR 0x00000001 +#define V_03C000_SQ_TEX_XY_FILTER_BICUBIC 0x00000002 +#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12) +#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7) +#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF +#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15) +#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3) +#define C_03C000_Z_FILTER 0xFFFE7FFF +#define V_03C000_SQ_TEX_Z_FILTER_NONE 0x00000000 +#define V_03C000_SQ_TEX_Z_FILTER_POINT 0x00000001 +#define V_03C000_SQ_TEX_Z_FILTER_LINEAR 0x00000002 +#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17) +#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3) +#define C_03C000_MIP_FILTER 0xFFF9FFFF +#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22) +#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3) +#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF +#define V_03C000_SQ_TEX_BORDER_COLOR_TRANS_BLACK 0x00000000 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK 0x00000001 +#define V_03C000_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE 0x00000002 +#define V_03C000_SQ_TEX_BORDER_COLOR_REGISTER 0x00000003 +#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24) +#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1) +#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF +#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25) +#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1) +#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF +#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26) +#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7) +#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NEVER 0x00000000 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESS 0x00000001 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_EQUAL 0x00000002 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_LESSEQUAL 0x00000003 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATER 0x00000004 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_NOTEQUAL 0x00000005 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL 0x00000006 +#define V_03C000_SQ_TEX_DEPTH_COMPARE_ALWAYS 0x00000007 +#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29) +#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3) +#define C_03C000_CHROMA_KEY 0x9FFFFFFF +#define V_03C000_SQ_TEX_CHROMA_KEY_DISABLE 0x00000000 +#define V_03C000_SQ_TEX_CHROMA_KEY_KILL 0x00000001 +#define V_03C000_SQ_TEX_CHROMA_KEY_BLEND 0x00000002 +#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31) +#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1) +#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF +#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004 +#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0) +#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF) +#define C_03C004_MIN_LOD 0xFFFFFC00 +#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10) +#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF) +#define C_03C004_MAX_LOD 0xFFF003FF +#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20) +#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF) +#define C_03C004_LOD_BIAS 0x000FFFFF +#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008 +#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0) +#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF) +#define C_03C008_LOD_BIAS_SEC 0xFFFFF000 +#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12) +#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1) +#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF +#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13) +#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1) +#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF +#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14) +#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1) +#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF +#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15) +#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7) +#define C_03C008_PERF_MIP 0xFFFC7FFF +#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18) +#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3) +#define C_03C008_PERF_Z 0xFFF3FFFF +#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26) +#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1) +#define C_03C008_FETCH_4 0xFBFFFFFF +#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27) +#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1) +#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF +#define S_03C008_TYPE(x) (((x) & 0x1) << 31) +#define G_03C008_TYPE(x) (((x) >> 31) & 0x1) +#define C_03C008_TYPE 0x7FFFFFFF #define R_008958_VGT_PRIMITIVE_TYPE 0x008958 #define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0) #define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F) |