diff options
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 52 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 12 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 44 |
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 |