summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2012-12-16 10:31:32 +0000
committerDave Airlie <airlied@redhat.com>2013-01-11 22:31:54 +0000
commitd23aa650015ec017649f5a4ce8cb12d8c314bd3a (patch)
treea76e70719be1969b929be5f96bc8f6993bfc653f
parent77c10225eef43eb428ebbc80f1dd426e3d33b281 (diff)
r600g: texture buffer object + glsl 1.40 enable support (v2)
This adds TBO support to r600g, and with GLSL 1.40 enabled, we now get 3.1 core profiles advertised for r600g. The r600/700 implementation is a bit different from the evergreen one, as r6/7 hw lacks vertex fetch swizzles. So we implement it by passing 5 constants per sampler to the shader, the shader uses the first 4 as masks for each component and the 5th as the alpha value to OR in. Now TXQ is also broken so we have to pass a constant for the buffer size, on evergreen we just pass this, on r6/7 we pass it as the 6th element in the const info buffer. v1.1: drop return as DDX doesn't use a texture type v2: add r600/700 support. Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c55
-rw-r--r--src/gallium/drivers/r600/r600_asm.c2
-rw-r--r--src/gallium/drivers/r600/r600_asm.h2
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c4
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h10
-rw-r--r--src/gallium/drivers/r600/r600_shader.c134
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
-rw-r--r--src/gallium/drivers/r600/r600_state.c43
-rw-r--r--src/gallium/drivers/r600/r600_state_common.c125
-rw-r--r--src/gallium/drivers/r600/r600_texture.c16
10 files changed, 373 insertions, 19 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index d0402c219fb..7040b7aa8cb 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -969,6 +969,58 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
969 return ss; 969 return ss;
970} 970}
971 971
972static struct pipe_sampler_view *
973texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
974 unsigned width0, unsigned height0)
975
976{
977 struct pipe_context *ctx = view->base.context;
978 struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
979 uint64_t va;
980 int stride = util_format_get_blocksize(view->base.format);
981 unsigned format, num_format, format_comp, endian;
982 unsigned swizzle_res;
983 unsigned char swizzle[4];
984 const struct util_format_description *desc;
985
986 swizzle[0] = view->base.swizzle_r;
987 swizzle[1] = view->base.swizzle_g;
988 swizzle[2] = view->base.swizzle_b;
989 swizzle[3] = view->base.swizzle_a;
990
991 r600_vertex_data_type(view->base.format,
992 &format, &num_format, &format_comp,
993 &endian);
994
995 desc = util_format_description(view->base.format);
996
997 swizzle_res = r600_get_swizzle_combined(desc->swizzle, swizzle, TRUE);
998
999 va = r600_resource_va(ctx->screen, view->base.texture);
1000 view->tex_resource = &tmp->resource;
1001
1002 view->skip_mip_address_reloc = true;
1003 view->tex_resource_words[0] = va;
1004 view->tex_resource_words[1] = width0 - 1;
1005 view->tex_resource_words[2] = S_030008_BASE_ADDRESS_HI(va >> 32UL) |
1006 S_030008_STRIDE(stride) |
1007 S_030008_DATA_FORMAT(format) |
1008 S_030008_NUM_FORMAT_ALL(num_format) |
1009 S_030008_FORMAT_COMP_ALL(format_comp) |
1010 S_030008_SRF_MODE_ALL(1) |
1011 S_030008_ENDIAN_SWAP(endian);
1012 view->tex_resource_words[3] = swizzle_res;
1013 /*
1014 * in theory dword 4 is for number of elements, for use with resinfo,
1015 * but it seems to utterly fail to work, the amd gpu shader analyser
1016 * uses a const buffer to store the element sizes for buffer txq
1017 */
1018 view->tex_resource_words[4] = 0;
1019 view->tex_resource_words[5] = view->tex_resource_words[6] = 0;
1020 view->tex_resource_words[7] = S_03001C_TYPE(V_03001C_SQ_TEX_VTX_VALID_BUFFER);
1021 return &view->base;
1022}
1023
972struct pipe_sampler_view * 1024struct pipe_sampler_view *
973evergreen_create_sampler_view_custom(struct pipe_context *ctx, 1025evergreen_create_sampler_view_custom(struct pipe_context *ctx,
974 struct pipe_resource *texture, 1026 struct pipe_resource *texture,
@@ -997,6 +1049,9 @@ evergreen_create_sampler_view_custom(struct pipe_context *ctx,
997 view->base.reference.count = 1; 1049 view->base.reference.count = 1;
998 view->base.context = ctx; 1050 view->base.context = ctx;
999 1051
1052 if (texture->target == PIPE_BUFFER)
1053 return texture_buffer_sampler_view(view, width0, height0);
1054
1000 swizzle[0] = state->swizzle_r; 1055 swizzle[0] = state->swizzle_r;
1001 swizzle[1] = state->swizzle_g; 1056 swizzle[1] = state->swizzle_g;
1002 swizzle[2] = state->swizzle_b; 1057 swizzle[2] = state->swizzle_b;
diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index d324d59f48d..0a6f63ff9c0 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2609,7 +2609,7 @@ void r600_bytecode_dump(struct r600_bytecode *bc)
2609 fprintf(stderr, "--------------------------------------\n"); 2609 fprintf(stderr, "--------------------------------------\n");
2610} 2610}
2611 2611
2612static void r600_vertex_data_type(enum pipe_format pformat, 2612void r600_vertex_data_type(enum pipe_format pformat,
2613 unsigned *format, 2613 unsigned *format,
2614 unsigned *num_format, unsigned *format_comp, unsigned *endian) 2614 unsigned *num_format, unsigned *format_comp, unsigned *endian)
2615{ 2615{
diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h
index 5727a7c421f..182f403aa77 100644
--- a/src/gallium/drivers/r600/r600_asm.h
+++ b/src/gallium/drivers/r600/r600_asm.h
@@ -250,4 +250,6 @@ void r700_bytecode_alu_read(struct r600_bytecode_alu *alu, uint32_t word0, uint3
250void r600_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1); 250void r600_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
251void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1); 251void eg_bytecode_export_read(struct r600_bytecode_output *output, uint32_t word0, uint32_t word1);
252 252
253void r600_vertex_data_type(enum pipe_format pformat, unsigned *format,
254 unsigned *num_format, unsigned *format_comp, unsigned *endian);
253#endif 255#endif
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 29ef988372b..92beabc74d0 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -416,6 +416,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
416 case PIPE_CAP_COMPUTE: 416 case PIPE_CAP_COMPUTE:
417 case PIPE_CAP_START_INSTANCE: 417 case PIPE_CAP_START_INSTANCE:
418 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: 418 case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
419 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
419 return 1; 420 return 1;
420 421
421 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: 422 case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
@@ -425,7 +426,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
425 return 256; 426 return 256;
426 427
427 case PIPE_CAP_GLSL_FEATURE_LEVEL: 428 case PIPE_CAP_GLSL_FEATURE_LEVEL:
428 return 130; 429 return 140;
429 430
430 case PIPE_CAP_TEXTURE_MULTISAMPLE: 431 case PIPE_CAP_TEXTURE_MULTISAMPLE:
431 return rscreen->msaa_texture_support != MSAA_TEXTURE_SAMPLE_ZERO; 432 return rscreen->msaa_texture_support != MSAA_TEXTURE_SAMPLE_ZERO;
@@ -450,7 +451,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
450 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: 451 case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
451 case PIPE_CAP_VERTEX_COLOR_CLAMPED: 452 case PIPE_CAP_VERTEX_COLOR_CLAMPED:
452 case PIPE_CAP_USER_VERTEX_BUFFERS: 453 case PIPE_CAP_USER_VERTEX_BUFFERS:
453 case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
454 return 0; 454 return 0;
455 455
456 /* Stream output. */ 456 /* Stream output. */
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 2dcb4734e6b..d983718b1bb 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -40,12 +40,13 @@
40#define R600_TRACE_CS 0 40#define R600_TRACE_CS 0
41 41
42#define R600_MAX_USER_CONST_BUFFERS 13 42#define R600_MAX_USER_CONST_BUFFERS 13
43#define R600_MAX_DRIVER_CONST_BUFFERS 2 43#define R600_MAX_DRIVER_CONST_BUFFERS 3
44#define R600_MAX_CONST_BUFFERS (R600_MAX_USER_CONST_BUFFERS + R600_MAX_DRIVER_CONST_BUFFERS) 44#define R600_MAX_CONST_BUFFERS (R600_MAX_USER_CONST_BUFFERS + R600_MAX_DRIVER_CONST_BUFFERS)
45 45
46/* start driver buffers after user buffers */ 46/* start driver buffers after user buffers */
47#define R600_UCP_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS) 47#define R600_UCP_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS)
48#define R600_TXQ_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 1) 48#define R600_TXQ_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 1)
49#define R600_BUFFER_INFO_CONST_BUFFER (R600_MAX_USER_CONST_BUFFERS + 2)
49 50
50#define R600_MAX_CONST_BUFFER_SIZE 4096 51#define R600_MAX_CONST_BUFFER_SIZE 4096
51 52
@@ -330,6 +331,7 @@ struct r600_samplerview_state {
330 uint32_t compressed_depthtex_mask; /* which textures are depth */ 331 uint32_t compressed_depthtex_mask; /* which textures are depth */
331 uint32_t compressed_colortex_mask; 332 uint32_t compressed_colortex_mask;
332 boolean dirty_txq_constants; 333 boolean dirty_txq_constants;
334 boolean dirty_buffer_constants;
333}; 335};
334 336
335struct r600_sampler_states { 337struct r600_sampler_states {
@@ -347,6 +349,8 @@ struct r600_textures_info {
347 349
348 /* cube array txq workaround */ 350 /* cube array txq workaround */
349 uint32_t *txq_constants; 351 uint32_t *txq_constants;
352 /* buffer related workarounds */
353 uint32_t *buffer_constants;
350}; 354};
351 355
352struct r600_fence { 356struct r600_fence {
@@ -678,6 +682,10 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
678 const struct pipe_surface *templ, 682 const struct pipe_surface *templ,
679 unsigned width, unsigned height); 683 unsigned width, unsigned height);
680 684
685unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
686 const unsigned char *swizzle_view,
687 boolean vtx);
688
681/* r600_state_common.c */ 689/* r600_state_common.c */
682void r600_init_common_state_functions(struct r600_context *rctx); 690void r600_init_common_state_functions(struct r600_context *rctx);
683void r600_emit_cso_state(struct r600_context *rctx, struct r600_atom *atom); 691void r600_emit_cso_state(struct r600_context *rctx, struct r600_atom *atom);
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index e0c2b44b5b1..83077504385 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -3896,6 +3896,128 @@ static inline unsigned tgsi_tex_get_src_gpr(struct r600_shader_ctx *ctx,
3896 return ctx->file_offset[inst->Src[index].Register.File] + inst->Src[index].Register.Index; 3896 return ctx->file_offset[inst->Src[index].Register.File] + inst->Src[index].Register.Index;
3897} 3897}
3898 3898
3899static int do_vtx_fetch_inst(struct r600_shader_ctx *ctx, boolean src_requires_loading)
3900{
3901 struct r600_bytecode_vtx vtx;
3902 struct r600_bytecode_alu alu;
3903 struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
3904 int src_gpr, r, i;
3905 int id = tgsi_tex_get_src_gpr(ctx, 1);
3906
3907 src_gpr = tgsi_tex_get_src_gpr(ctx, 0);
3908 if (src_requires_loading) {
3909 for (i = 0; i < 4; i++) {
3910 memset(&alu, 0, sizeof(struct r600_bytecode_alu));
3911 alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
3912 r600_bytecode_src(&alu.src[0], &ctx->src[0], i);
3913 alu.dst.sel = ctx->temp_reg;
3914 alu.dst.chan = i;
3915 if (i == 3)
3916 alu.last = 1;
3917 alu.dst.write = 1;
3918 r = r600_bytecode_add_alu(ctx->bc, &alu);
3919 if (r)
3920 return r;
3921 }
3922 src_gpr = ctx->temp_reg;
3923 }
3924
3925 memset(&vtx, 0, sizeof(vtx));
3926 vtx.inst = 0;
3927 vtx.buffer_id = id + R600_MAX_CONST_BUFFERS;
3928 vtx.fetch_type = 2; /* VTX_FETCH_NO_INDEX_OFFSET */
3929 vtx.src_gpr = src_gpr;
3930 vtx.mega_fetch_count = 16;
3931 vtx.dst_gpr = ctx->file_offset[inst->Dst[0].Register.File] + inst->Dst[0].Register.Index;
3932 vtx.dst_sel_x = (inst->Dst[0].Register.WriteMask & 1) ? 0 : 7; /* SEL_X */
3933 vtx.dst_sel_y = (inst->Dst[0].Register.WriteMask & 2) ? 1 : 7; /* SEL_Y */
3934 vtx.dst_sel_z = (inst->Dst[0].Register.WriteMask & 4) ? 2 : 7; /* SEL_Z */
3935 vtx.dst_sel_w = (inst->Dst[0].Register.WriteMask & 8) ? 3 : 7; /* SEL_W */
3936 vtx.use_const_fields = 1;
3937 vtx.srf_mode_all = 1; /* SRF_MODE_NO_ZERO */
3938
3939 if ((r = r600_bytecode_add_vtx(ctx->bc, &vtx)))
3940 return r;
3941
3942 if (ctx->bc->chip_class >= EVERGREEN)
3943 return 0;
3944
3945 for (i = 0; i < 4; i++) {
3946 int lasti = tgsi_last_instruction(inst->Dst[0].Register.WriteMask);
3947 if (!(inst->Dst[0].Register.WriteMask & (1 << i)))
3948 continue;
3949
3950 memset(&alu, 0, sizeof(struct r600_bytecode_alu));
3951 alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT);
3952
3953 alu.dst.chan = i;
3954 alu.dst.sel = vtx.dst_gpr;
3955 alu.dst.write = 1;
3956
3957 alu.src[0].sel = vtx.dst_gpr;
3958 alu.src[0].chan = i;
3959
3960 alu.src[1].sel = 512 + (id * 2);
3961 alu.src[1].chan = i % 4;
3962 alu.src[1].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
3963
3964 if (i == lasti)
3965 alu.last = 1;
3966 r = r600_bytecode_add_alu(ctx->bc, &alu);
3967 if (r)
3968 return r;
3969 }
3970
3971 if (inst->Dst[0].Register.WriteMask & 3) {
3972 memset(&alu, 0, sizeof(struct r600_bytecode_alu));
3973 alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT);
3974
3975 alu.dst.chan = 3;
3976 alu.dst.sel = vtx.dst_gpr;
3977 alu.dst.write = 1;
3978
3979 alu.src[0].sel = vtx.dst_gpr;
3980 alu.src[0].chan = 3;
3981
3982 alu.src[1].sel = 512 + (id * 2) + 1;
3983 alu.src[1].chan = 0;
3984 alu.src[1].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
3985
3986 alu.last = 1;
3987 r = r600_bytecode_add_alu(ctx->bc, &alu);
3988 if (r)
3989 return r;
3990 }
3991 return 0;
3992}
3993
3994static int r600_do_buffer_txq(struct r600_shader_ctx *ctx)
3995{
3996 struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction;
3997 struct r600_bytecode_alu alu;
3998 int r;
3999 int id = tgsi_tex_get_src_gpr(ctx, 1);
4000
4001 memset(&alu, 0, sizeof(struct r600_bytecode_alu));
4002 alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV);
4003
4004 if (ctx->bc->chip_class >= EVERGREEN) {
4005 alu.src[0].sel = 512 + (id / 4);
4006 alu.src[0].chan = id % 4;
4007 } else {
4008 /* r600 we have them at channel 2 of the second dword */
4009 alu.src[0].sel = 512 + (id * 2) + 1;
4010 alu.src[0].chan = 1;
4011 }
4012 alu.src[0].kc_bank = R600_BUFFER_INFO_CONST_BUFFER;
4013 tgsi_dst(ctx, &inst->Dst[0], 0, &alu.dst);
4014 alu.last = 1;
4015 r = r600_bytecode_add_alu(ctx->bc, &alu);
4016 if (r)
4017 return r;
4018 return 0;
4019}
4020
3899static int tgsi_tex(struct r600_shader_ctx *ctx) 4021static int tgsi_tex(struct r600_shader_ctx *ctx)
3900{ 4022{
3901 static float one_point_five = 1.5f; 4023 static float one_point_five = 1.5f;
@@ -3934,6 +4056,18 @@ static int tgsi_tex(struct r600_shader_ctx *ctx)
3934 4056
3935 src_gpr = tgsi_tex_get_src_gpr(ctx, 0); 4057 src_gpr = tgsi_tex_get_src_gpr(ctx, 0);
3936 4058
4059 if (inst->Texture.Texture == TGSI_TEXTURE_BUFFER) {
4060 if (inst->Instruction.Opcode == TGSI_OPCODE_TXQ) {
4061 ctx->shader->uses_tex_buffers = true;
4062 return r600_do_buffer_txq(ctx);
4063 }
4064 else if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
4065 if (ctx->bc->chip_class < EVERGREEN)
4066 ctx->shader->uses_tex_buffers = true;
4067 return do_vtx_fetch_inst(ctx, src_requires_loading);
4068 }
4069 }
4070
3937 if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) { 4071 if (inst->Instruction.Opcode == TGSI_OPCODE_TXF) {
3938 /* get offset values */ 4072 /* get offset values */
3939 if (inst->Texture.NumOffsets) { 4073 if (inst->Texture.NumOffsets) {
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index b58a58ab4db..d61efcb1a72 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -61,6 +61,7 @@ struct r600_shader {
61 boolean vs_out_misc_write; 61 boolean vs_out_misc_write;
62 boolean vs_out_point_size; 62 boolean vs_out_point_size;
63 boolean has_txq_cube_array_z_comp; 63 boolean has_txq_cube_array_z_comp;
64 boolean uses_tex_buffers;
64}; 65};
65 66
66struct r600_shader_key { 67struct r600_shader_key {
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index e2d0f7544c1..17c5a64e9e7 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -976,6 +976,46 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
976 return ss; 976 return ss;
977} 977}
978 978
979static struct pipe_sampler_view *
980texture_buffer_sampler_view(struct r600_pipe_sampler_view *view,
981 unsigned width0, unsigned height0)
982
983{
984 struct pipe_context *ctx = view->base.context;
985 struct r600_texture *tmp = (struct r600_texture*)view->base.texture;
986 uint64_t va;
987 int stride = util_format_get_blocksize(view->base.format);
988 unsigned format, num_format, format_comp, endian;
989
990 r600_vertex_data_type(view->base.format,
991 &format, &num_format, &format_comp,
992 &endian);
993
994 va = r600_resource_va(ctx->screen, view->base.texture);
995 view->tex_resource = &tmp->resource;
996
997 view->skip_mip_address_reloc = true;
998 view->tex_resource_words[0] = va;
999 view->tex_resource_words[1] = width0 - 1;
1000 view->tex_resource_words[2] = S_038008_BASE_ADDRESS_HI(va >> 32UL) |
1001 S_038008_STRIDE(stride) |
1002 S_038008_DATA_FORMAT(format) |
1003 S_038008_NUM_FORMAT_ALL(num_format) |
1004 S_038008_FORMAT_COMP_ALL(format_comp) |
1005 S_038008_SRF_MODE_ALL(1) |
1006 S_038008_ENDIAN_SWAP(endian);
1007 view->tex_resource_words[3] = 0;
1008 /*
1009 * in theory dword 4 is for number of elements, for use with resinfo,
1010 * but it seems to utterly fail to work, the amd gpu shader analyser
1011 * uses a const buffer to store the element sizes for buffer txq
1012 */
1013 view->tex_resource_words[4] = 0;
1014 view->tex_resource_words[5] = 0;
1015 view->tex_resource_words[6] = S_038018_TYPE(V_038010_SQ_TEX_VTX_VALID_BUFFER);
1016 return &view->base;
1017}
1018
979struct pipe_sampler_view * 1019struct pipe_sampler_view *
980r600_create_sampler_view_custom(struct pipe_context *ctx, 1020r600_create_sampler_view_custom(struct pipe_context *ctx,
981 struct pipe_resource *texture, 1021 struct pipe_resource *texture,
@@ -1000,6 +1040,9 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
1000 view->base.reference.count = 1; 1040 view->base.reference.count = 1;
1001 view->base.context = ctx; 1041 view->base.context = ctx;
1002 1042
1043 if (texture->target == PIPE_BUFFER)
1044 return texture_buffer_sampler_view(view, texture->width0, 1);
1045
1003 swizzle[0] = state->swizzle_r; 1046 swizzle[0] = state->swizzle_r;
1004 swizzle[1] = state->swizzle_g; 1047 swizzle[1] = state->swizzle_g;
1005 swizzle[2] = state->swizzle_b; 1048 swizzle[2] = state->swizzle_b;
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 3b61413f84e..34977373d21 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -588,19 +588,20 @@ static void r600_set_sampler_views(struct pipe_context *pipe, unsigned shader,
588 struct r600_texture *rtex = 588 struct r600_texture *rtex =
589 (struct r600_texture*)rviews[i]->base.texture; 589 (struct r600_texture*)rviews[i]->base.texture;
590 590
591 if (rtex->is_depth && !rtex->is_flushing_texture) { 591 if (rviews[i]->base.texture->target != PIPE_BUFFER) {
592 dst->views.compressed_depthtex_mask |= 1 << i; 592 if (rtex->is_depth && !rtex->is_flushing_texture) {
593 } else { 593 dst->views.compressed_depthtex_mask |= 1 << i;
594 dst->views.compressed_depthtex_mask &= ~(1 << i); 594 } else {
595 } 595 dst->views.compressed_depthtex_mask &= ~(1 << i);
596 }
596 597
597 /* Track compressed colorbuffers. */ 598 /* Track compressed colorbuffers. */
598 if (rtex->cmask_size && rtex->fmask_size) { 599 if (rtex->cmask_size && rtex->fmask_size) {
599 dst->views.compressed_colortex_mask |= 1 << i; 600 dst->views.compressed_colortex_mask |= 1 << i;
600 } else { 601 } else {
601 dst->views.compressed_colortex_mask &= ~(1 << i); 602 dst->views.compressed_colortex_mask &= ~(1 << i);
603 }
602 } 604 }
603
604 /* Changing from array to non-arrays textures and vice versa requires 605 /* Changing from array to non-arrays textures and vice versa requires
605 * updating TEX_ARRAY_OVERRIDE in sampler states on R6xx-R7xx. */ 606 * updating TEX_ARRAY_OVERRIDE in sampler states on R6xx-R7xx. */
606 if (rctx->chip_class <= R700 && 607 if (rctx->chip_class <= R700 &&
@@ -625,6 +626,7 @@ static void r600_set_sampler_views(struct pipe_context *pipe, unsigned shader,
625 dst->views.compressed_depthtex_mask &= dst->views.enabled_mask; 626 dst->views.compressed_depthtex_mask &= dst->views.enabled_mask;
626 dst->views.compressed_colortex_mask &= dst->views.enabled_mask; 627 dst->views.compressed_colortex_mask &= dst->views.enabled_mask;
627 dst->views.dirty_txq_constants = TRUE; 628 dst->views.dirty_txq_constants = TRUE;
629 dst->views.dirty_buffer_constants = TRUE;
628 r600_sampler_views_dirty(rctx, &dst->views); 630 r600_sampler_views_dirty(rctx, &dst->views);
629 631
630 if (dirty_sampler_states_mask) { 632 if (dirty_sampler_states_mask) {
@@ -1023,6 +1025,92 @@ static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask
1023 rctx->sample_mask.atom.dirty = true; 1025 rctx->sample_mask.atom.dirty = true;
1024} 1026}
1025 1027
1028/*
1029 * On r600/700 hw we don't have vertex fetch swizzle, though TBO
1030 * doesn't require full swizzles it does need masking and setting alpha
1031 * to one, so we setup a set of 5 constants with the masks + alpha value
1032 * then in the shader, we AND the 4 components with 0xffffffff or 0,
1033 * then OR the alpha with the value given here.
1034 * We use a 6th constant to store the txq buffer size in
1035 */
1036static void r600_setup_buffer_constants(struct r600_context *rctx, int shader_type)
1037{
1038 struct r600_textures_info *samplers = &rctx->samplers[shader_type];
1039 int bits;
1040 uint32_t array_size;
1041 struct pipe_constant_buffer cb;
1042 int i, j;
1043
1044 if (!samplers->views.dirty_buffer_constants)
1045 return;
1046
1047 samplers->views.dirty_buffer_constants = FALSE;
1048
1049 bits = util_last_bit(samplers->views.enabled_mask);
1050 array_size = bits * 8 * sizeof(uint32_t) * 4;
1051 samplers->buffer_constants = realloc(samplers->buffer_constants, array_size);
1052 memset(samplers->buffer_constants, 0, array_size);
1053 for (i = 0; i < bits; i++) {
1054 if (samplers->views.enabled_mask & (1 << i)) {
1055 int offset = i * 8;
1056 const struct util_format_description *desc;
1057 desc = util_format_description(samplers->views.views[i]->base.format);
1058
1059 for (j = 0; j < 4; j++)
1060 if (j < desc->nr_channels)
1061 samplers->buffer_constants[offset+j] = 0xffffffff;
1062 else
1063 samplers->buffer_constants[offset+j] = 0x0;
1064 if (desc->nr_channels < 4) {
1065 if (desc->channel[0].pure_integer)
1066 samplers->buffer_constants[offset+4] = 1;
1067 else
1068 samplers->buffer_constants[offset+4] = 0x3f800000;
1069 } else
1070 samplers->buffer_constants[offset + 4] = 0;
1071
1072 samplers->buffer_constants[offset + 5] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
1073 }
1074 }
1075
1076 cb.buffer = NULL;
1077 cb.user_buffer = samplers->buffer_constants;
1078 cb.buffer_offset = 0;
1079 cb.buffer_size = array_size;
1080 rctx->context.set_constant_buffer(&rctx->context, shader_type, R600_BUFFER_INFO_CONST_BUFFER, &cb);
1081 pipe_resource_reference(&cb.buffer, NULL);
1082}
1083
1084/* On evergreen we only need to store the buffer size for TXQ */
1085static void eg_setup_buffer_constants(struct r600_context *rctx, int shader_type)
1086{
1087 struct r600_textures_info *samplers = &rctx->samplers[shader_type];
1088 int bits;
1089 uint32_t array_size;
1090 struct pipe_constant_buffer cb;
1091 int i;
1092
1093 if (!samplers->views.dirty_buffer_constants)
1094 return;
1095
1096 samplers->views.dirty_buffer_constants = FALSE;
1097
1098 bits = util_last_bit(samplers->views.enabled_mask);
1099 array_size = bits * sizeof(uint32_t) * 4;
1100 samplers->buffer_constants = realloc(samplers->buffer_constants, array_size);
1101 memset(samplers->buffer_constants, 0, array_size);
1102 for (i = 0; i < bits; i++)
1103 if (samplers->views.enabled_mask & (1 << i))
1104 samplers->buffer_constants[i] = samplers->views.views[i]->base.texture->width0 / util_format_get_blocksize(samplers->views.views[i]->base.format);
1105
1106 cb.buffer = NULL;
1107 cb.user_buffer = samplers->buffer_constants;
1108 cb.buffer_offset = 0;
1109 cb.buffer_size = array_size;
1110 rctx->context.set_constant_buffer(&rctx->context, shader_type, R600_BUFFER_INFO_CONST_BUFFER, &cb);
1111 pipe_resource_reference(&cb.buffer, NULL);
1112}
1113
1026static void r600_setup_txq_cube_array_constants(struct r600_context *rctx, int shader_type) 1114static void r600_setup_txq_cube_array_constants(struct r600_context *rctx, int shader_type)
1027{ 1115{
1028 struct r600_textures_info *samplers = &rctx->samplers[shader_type]; 1116 struct r600_textures_info *samplers = &rctx->samplers[shader_type];
@@ -1090,6 +1178,21 @@ static bool r600_update_derived_state(struct r600_context *rctx)
1090 if (ps_dirty) 1178 if (ps_dirty)
1091 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate); 1179 r600_context_pipe_state_set(rctx, &rctx->ps_shader->current->rstate);
1092 1180
1181 /* on R600 we stuff masks + txq info into one constant buffer */
1182 /* on evergreen we only need a txq info one */
1183 if (rctx->chip_class < EVERGREEN) {
1184 if (rctx->ps_shader && rctx->ps_shader->current->shader.uses_tex_buffers)
1185 r600_setup_buffer_constants(rctx, PIPE_SHADER_FRAGMENT);
1186 if (rctx->vs_shader && rctx->vs_shader->current->shader.uses_tex_buffers)
1187 r600_setup_buffer_constants(rctx, PIPE_SHADER_VERTEX);
1188 } else {
1189 if (rctx->ps_shader && rctx->ps_shader->current->shader.uses_tex_buffers)
1190 eg_setup_buffer_constants(rctx, PIPE_SHADER_FRAGMENT);
1191 if (rctx->vs_shader && rctx->vs_shader->current->shader.uses_tex_buffers)
1192 eg_setup_buffer_constants(rctx, PIPE_SHADER_VERTEX);
1193 }
1194
1195
1093 if (rctx->ps_shader && rctx->ps_shader->current->shader.has_txq_cube_array_z_comp) 1196 if (rctx->ps_shader && rctx->ps_shader->current->shader.has_txq_cube_array_z_comp)
1094 r600_setup_txq_cube_array_constants(rctx, PIPE_SHADER_FRAGMENT); 1197 r600_setup_txq_cube_array_constants(rctx, PIPE_SHADER_FRAGMENT);
1095 if (rctx->vs_shader && rctx->vs_shader->current->shader.has_txq_cube_array_z_comp) 1198 if (rctx->vs_shader && rctx->vs_shader->current->shader.has_txq_cube_array_z_comp)
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
index 85da0930242..45a30f85df4 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -912,18 +912,26 @@ void r600_init_surface_functions(struct r600_context *r600)
912 r600->context.surface_destroy = r600_surface_destroy; 912 r600->context.surface_destroy = r600_surface_destroy;
913} 913}
914 914
915static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format, 915unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
916 const unsigned char *swizzle_view) 916 const unsigned char *swizzle_view,
917 boolean vtx)
917{ 918{
918 unsigned i; 919 unsigned i;
919 unsigned char swizzle[4]; 920 unsigned char swizzle[4];
920 unsigned result = 0; 921 unsigned result = 0;
921 const uint32_t swizzle_shift[4] = { 922 const uint32_t tex_swizzle_shift[4] = {
922 16, 19, 22, 25, 923 16, 19, 22, 25,
923 }; 924 };
925 const uint32_t vtx_swizzle_shift[4] = {
926 3, 6, 9, 12,
927 };
924 const uint32_t swizzle_bit[4] = { 928 const uint32_t swizzle_bit[4] = {
925 0, 1, 2, 3, 929 0, 1, 2, 3,
926 }; 930 };
931 const uint32_t *swizzle_shift = tex_swizzle_shift;
932
933 if (vtx)
934 swizzle_shift = vtx_swizzle_shift;
927 935
928 if (swizzle_view) { 936 if (swizzle_view) {
929 util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle); 937 util_format_compose_swizzles(swizzle_format, swizzle_view, swizzle);
@@ -977,7 +985,7 @@ uint32_t r600_translate_texformat(struct pipe_screen *screen,
977 }; 985 };
978 desc = util_format_description(format); 986 desc = util_format_description(format);
979 987
980 word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view); 988 word4 |= r600_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE);
981 989
982 /* Colorspace (return non-RGB formats directly). */ 990 /* Colorspace (return non-RGB formats directly). */
983 switch (desc->colorspace) { 991 switch (desc->colorspace) {