summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2017-02-16 01:17:48 +0100
committerMarek Olšák <[email protected]>2017-02-18 01:22:08 +0100
commitdbd38f2a92633e565fe35c8d9c66f864d6ff4877 (patch)
tree55d8a0efe8fb24624c12fd647e7fc5e8275fbc8d
parent41a2157a689838e4c97d5a703bc2aeaf5a5e1b48 (diff)
radeonsi: add a workaround for clamping unaligned RGB 8 & 16-bit vertex loads
Reviewed-by: Nicolai Hähnle <[email protected]>
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c38
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h4
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_internal.h3
-rw-r--r--src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c3
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c18
5 files changed, 60 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 8b9fed9fb8c..1829e3ec118 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -368,14 +368,27 @@ static void declare_input_vs(
fix_fetch = ctx->shader->key.mono.vs.fix_fetch[input_index];
- /* Do multiple loads for double formats. */
- if (fix_fetch == SI_FIX_FETCH_RGB_64_FLOAT) {
+ /* Do multiple loads for special formats. */
+ switch (fix_fetch) {
+ case SI_FIX_FETCH_RGB_64_FLOAT:
num_fetches = 3; /* 3 2-dword loads */
fetch_stride = 8;
- } else if (fix_fetch == SI_FIX_FETCH_RGBA_64_FLOAT) {
+ break;
+ case SI_FIX_FETCH_RGBA_64_FLOAT:
num_fetches = 2; /* 2 4-dword loads */
fetch_stride = 16;
- } else {
+ break;
+ case SI_FIX_FETCH_RGB_8:
+ case SI_FIX_FETCH_RGB_8_INT:
+ num_fetches = 3;
+ fetch_stride = 1;
+ break;
+ case SI_FIX_FETCH_RGB_16:
+ case SI_FIX_FETCH_RGB_16_INT:
+ num_fetches = 3;
+ fetch_stride = 2;
+ break;
+ default:
num_fetches = 1;
fetch_stride = 0;
}
@@ -512,6 +525,23 @@ static void declare_input_vs(
chan % 2);
}
break;
+ case SI_FIX_FETCH_RGB_8:
+ case SI_FIX_FETCH_RGB_8_INT:
+ case SI_FIX_FETCH_RGB_16:
+ case SI_FIX_FETCH_RGB_16_INT:
+ for (chan = 0; chan < 3; chan++) {
+ out[chan] = LLVMBuildExtractElement(gallivm->builder,
+ input[chan],
+ ctx->i32_0, "");
+ }
+ if (fix_fetch == SI_FIX_FETCH_RGB_8 ||
+ fix_fetch == SI_FIX_FETCH_RGB_16) {
+ out[3] = LLVMConstReal(ctx->f32, 1);
+ } else {
+ out[3] = LLVMBuildBitCast(gallivm->builder, ctx->i32_1,
+ ctx->f32, "");
+ }
+ break;
}
}
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 46161907a67..da88df041ca 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -250,6 +250,10 @@ enum {
SI_FIX_FETCH_RG_64_FLOAT,
SI_FIX_FETCH_RGB_64_FLOAT,
SI_FIX_FETCH_RGBA_64_FLOAT,
+ SI_FIX_FETCH_RGB_8, /* A = 1.0 */
+ SI_FIX_FETCH_RGB_8_INT, /* A = 1 */
+ SI_FIX_FETCH_RGB_16,
+ SI_FIX_FETCH_RGB_16_INT,
};
struct si_shader;
diff --git a/src/gallium/drivers/radeonsi/si_shader_internal.h b/src/gallium/drivers/radeonsi/si_shader_internal.h
index 26cc28d8079..8fde6c25684 100644
--- a/src/gallium/drivers/radeonsi/si_shader_internal.h
+++ b/src/gallium/drivers/radeonsi/si_shader_internal.h
@@ -149,6 +149,9 @@ struct si_shader_context {
LLVMTypeRef v4f32;
LLVMTypeRef v8i32;
+ LLVMValueRef i32_0;
+ LLVMValueRef i32_1;
+
LLVMValueRef shared_memory;
};
diff --git a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
index c7445e037a3..c7019c1b8b7 100644
--- a/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
+++ b/src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c
@@ -1366,6 +1366,9 @@ void si_llvm_context_init(struct si_shader_context *ctx,
ctx->v4i32 = LLVMVectorType(ctx->i32, 4);
ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
+
+ ctx->i32_0 = LLVMConstInt(ctx->i32, 0, 0);
+ ctx->i32_1 = LLVMConstInt(ctx->i32, 1, 0);
}
void si_llvm_create_func(struct si_shader_context *ctx,
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index d9b9f838763..024de8b035e 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1732,10 +1732,10 @@ static uint32_t si_translate_buffer_dataformat(struct pipe_screen *screen,
case 8:
switch (desc->nr_channels) {
case 1:
+ case 3: /* 3 loads */
return V_008F0C_BUF_DATA_FORMAT_8;
case 2:
return V_008F0C_BUF_DATA_FORMAT_8_8;
- case 3:
case 4:
return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
}
@@ -1743,10 +1743,10 @@ static uint32_t si_translate_buffer_dataformat(struct pipe_screen *screen,
case 16:
switch (desc->nr_channels) {
case 1:
+ case 3: /* 3 loads */
return V_008F0C_BUF_DATA_FORMAT_16;
case 2:
return V_008F0C_BUF_DATA_FORMAT_16_16;
- case 3:
case 4:
return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
}
@@ -3459,6 +3459,20 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
default:
assert(0);
}
+ } else if (channel && desc->nr_channels == 3) {
+ assert(desc->swizzle[0] == PIPE_SWIZZLE_X);
+
+ if (channel->size == 8) {
+ if (channel->pure_integer)
+ v->fix_fetch[i] = SI_FIX_FETCH_RGB_8_INT;
+ else
+ v->fix_fetch[i] = SI_FIX_FETCH_RGB_8;
+ } else if (channel->size == 16) {
+ if (channel->pure_integer)
+ v->fix_fetch[i] = SI_FIX_FETCH_RGB_16_INT;
+ else
+ v->fix_fetch[i] = SI_FIX_FETCH_RGB_16;
+ }
}
v->rsrc_word3[i] = S_008F0C_DST_SEL_X(si_map_swizzle(swizzle[0])) |