summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.c52
-rw-r--r--src/gallium/drivers/radeonsi/si_shader.h12
-rw-r--r--src/gallium/drivers/radeonsi/si_state.c44
3 files changed, 90 insertions, 18 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index ddb6ca1ae17..840b3790f04 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -434,7 +434,11 @@ static void declare_input_vs(
}
fix_fetch = (ctx->shader->key.mono.vs.fix_fetch >> (4 * input_index)) & 0xf;
- if (fix_fetch) {
+
+ switch (fix_fetch) {
+ case SI_FIX_FETCH_A2_SNORM:
+ case SI_FIX_FETCH_A2_SSCALED:
+ case SI_FIX_FETCH_A2_SINT: {
/* The hardware returns an unsigned value; convert it to a
* signed one.
*/
@@ -470,6 +474,52 @@ static void declare_input_vs(
}
out[3] = tmp;
+ break;
+ }
+ case SI_FIX_FETCH_RGBA_32_UNORM:
+ case SI_FIX_FETCH_RGBX_32_UNORM:
+ for (chan = 0; chan < 4; chan++) {
+ out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
+ ctx->i32, "");
+ out[chan] = LLVMBuildUIToFP(gallivm->builder,
+ out[chan], ctx->f32, "");
+ out[chan] = LLVMBuildFMul(gallivm->builder, out[chan],
+ LLVMConstReal(ctx->f32, 1.0 / UINT_MAX), "");
+ }
+ /* RGBX UINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
+ if (fix_fetch == SI_FIX_FETCH_RGBX_32_UNORM)
+ out[3] = LLVMConstReal(ctx->f32, 1);
+ break;
+ case SI_FIX_FETCH_RGBA_32_SNORM:
+ case SI_FIX_FETCH_RGBX_32_SNORM:
+ for (chan = 0; chan < 4; chan++) {
+ out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
+ ctx->i32, "");
+ out[chan] = LLVMBuildSIToFP(gallivm->builder,
+ out[chan], ctx->f32, "");
+ out[chan] = LLVMBuildFMul(gallivm->builder, out[chan],
+ LLVMConstReal(ctx->f32, 1.0 / INT_MAX), "");
+ }
+ /* RGBX SINT returns 1 in alpha, which would be rounded to 0 by normalizing. */
+ if (fix_fetch == SI_FIX_FETCH_RGBX_32_SNORM)
+ out[3] = LLVMConstReal(ctx->f32, 1);
+ break;
+ case SI_FIX_FETCH_RGBA_32_USCALED:
+ for (chan = 0; chan < 4; chan++) {
+ out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
+ ctx->i32, "");
+ out[chan] = LLVMBuildUIToFP(gallivm->builder,
+ out[chan], ctx->f32, "");
+ }
+ break;
+ case SI_FIX_FETCH_RGBA_32_SSCALED:
+ for (chan = 0; chan < 4; chan++) {
+ out[chan] = LLVMBuildBitCast(gallivm->builder, out[chan],
+ ctx->i32, "");
+ out[chan] = LLVMBuildSIToFP(gallivm->builder,
+ out[chan], ctx->f32, "");
+ }
+ break;
}
}
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index 89f9628a1f6..5e554d9afe3 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -236,9 +236,15 @@ enum {
/* For VS shader key fix_fetch. */
enum {
SI_FIX_FETCH_NONE = 0,
- SI_FIX_FETCH_A2_SNORM = 1,
- SI_FIX_FETCH_A2_SSCALED = 2,
- SI_FIX_FETCH_A2_SINT = 3,
+ SI_FIX_FETCH_A2_SNORM,
+ SI_FIX_FETCH_A2_SSCALED,
+ SI_FIX_FETCH_A2_SINT,
+ SI_FIX_FETCH_RGBA_32_UNORM,
+ SI_FIX_FETCH_RGBX_32_UNORM,
+ SI_FIX_FETCH_RGBA_32_SNORM,
+ SI_FIX_FETCH_RGBX_32_SNORM,
+ SI_FIX_FETCH_RGBA_32_USCALED,
+ SI_FIX_FETCH_RGBA_32_SSCALED,
};
struct si_shader;
diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c
index fa78a56f73e..c8d1099421c 100644
--- a/src/gallium/drivers/radeonsi/si_state.c
+++ b/src/gallium/drivers/radeonsi/si_state.c
@@ -1746,14 +1746,6 @@ static uint32_t si_translate_buffer_dataformat(struct pipe_screen *screen,
}
break;
case 32:
- /* From the Southern Islands ISA documentation about MTBUF:
- * 'Memory reads of data in memory that is 32 or 64 bits do not
- * undergo any format conversion.'
- */
- if (type != UTIL_FORMAT_TYPE_FLOAT &&
- !desc->channel[first_non_void].pure_integer)
- return V_008F0C_BUF_DATA_FORMAT_INVALID;
-
switch (desc->nr_channels) {
case 1:
return V_008F0C_BUF_DATA_FORMAT_32;
@@ -1781,18 +1773,20 @@ static uint32_t si_translate_buffer_numformat(struct pipe_screen *screen,
switch (desc->channel[first_non_void].type) {
case UTIL_FORMAT_TYPE_SIGNED:
- if (desc->channel[first_non_void].normalized)
- return V_008F0C_BUF_NUM_FORMAT_SNORM;
- else if (desc->channel[first_non_void].pure_integer)
+ if (desc->channel[first_non_void].size >= 32 ||
+ desc->channel[first_non_void].pure_integer)
return V_008F0C_BUF_NUM_FORMAT_SINT;
+ else if (desc->channel[first_non_void].normalized)
+ return V_008F0C_BUF_NUM_FORMAT_SNORM;
else
return V_008F0C_BUF_NUM_FORMAT_SSCALED;
break;
case UTIL_FORMAT_TYPE_UNSIGNED:
- if (desc->channel[first_non_void].normalized)
- return V_008F0C_BUF_NUM_FORMAT_UNORM;
- else if (desc->channel[first_non_void].pure_integer)
+ if (desc->channel[first_non_void].size >= 32 ||
+ desc->channel[first_non_void].pure_integer)
return V_008F0C_BUF_NUM_FORMAT_UINT;
+ else if (desc->channel[first_non_void].normalized)
+ return V_008F0C_BUF_NUM_FORMAT_UNORM;
else
return V_008F0C_BUF_NUM_FORMAT_USCALED;
break;
@@ -3342,6 +3336,7 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
v->count = count;
for (i = 0; i < count; ++i) {
const struct util_format_description *desc;
+ const struct util_format_channel_description *channel;
unsigned data_format, num_format;
int first_non_void;
@@ -3349,6 +3344,7 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
first_non_void = util_format_get_first_non_void_channel(elements[i].src_format);
data_format = si_translate_buffer_dataformat(ctx->screen, desc, first_non_void);
num_format = si_translate_buffer_numformat(ctx->screen, desc, first_non_void);
+ channel = &desc->channel[first_non_void];
v->rsrc_word3[i] = S_008F0C_DST_SEL_X(si_map_swizzle(desc->swizzle[0])) |
S_008F0C_DST_SEL_Y(si_map_swizzle(desc->swizzle[1])) |
@@ -3370,6 +3366,26 @@ static void *si_create_vertex_elements(struct pipe_context *ctx,
/* This isn't actually used in OpenGL. */
v->fix_fetch |= (uint64_t)SI_FIX_FETCH_A2_SINT << (4 * i);
}
+ } else if (channel->size == 32 && !channel->pure_integer) {
+ if (channel->type == UTIL_FORMAT_TYPE_SIGNED) {
+ if (channel->normalized) {
+ if (desc->swizzle[3] == PIPE_SWIZZLE_1)
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBX_32_SNORM << (4 * i);
+ else
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBA_32_SNORM << (4 * i);
+ } else {
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBA_32_SSCALED << (4 * i);
+ }
+ } else if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED) {
+ if (channel->normalized) {
+ if (desc->swizzle[3] == PIPE_SWIZZLE_1)
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBX_32_UNORM << (4 * i);
+ else
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBA_32_UNORM << (4 * i);
+ } else {
+ v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBA_32_USCALED << (4 * i);
+ }
+ }
}
/* We work around the fact that 8_8_8 and 16_16_16 data formats