diff options
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_shader.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state.c | 11 |
3 files changed, 20 insertions, 7 deletions
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index 840b3790f04..f404273243f 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -492,18 +492,28 @@ static void declare_input_vs( break; case SI_FIX_FETCH_RGBA_32_SNORM: case SI_FIX_FETCH_RGBX_32_SNORM: + case SI_FIX_FETCH_RGBA_32_FIXED: + case SI_FIX_FETCH_RGBX_32_FIXED: { + double scale; + if (fix_fetch >= SI_FIX_FETCH_RGBA_32_FIXED) + scale = 1.0 / 0x10000; + else + scale = 1.0 / INT_MAX; + 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), ""); + LLVMConstReal(ctx->f32, scale), ""); } /* RGBX SINT returns 1 in alpha, which would be rounded to 0 by normalizing. */ - if (fix_fetch == SI_FIX_FETCH_RGBX_32_SNORM) + if (fix_fetch == SI_FIX_FETCH_RGBX_32_SNORM || + fix_fetch == SI_FIX_FETCH_RGBX_32_FIXED) 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], diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 5e554d9afe3..758403518f6 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -245,6 +245,8 @@ enum { SI_FIX_FETCH_RGBX_32_SNORM, SI_FIX_FETCH_RGBA_32_USCALED, SI_FIX_FETCH_RGBA_32_SSCALED, + SI_FIX_FETCH_RGBA_32_FIXED, + SI_FIX_FETCH_RGBX_32_FIXED, }; struct si_shader; diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index c8d1099421c..865a75dbe64 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1697,17 +1697,12 @@ static uint32_t si_translate_buffer_dataformat(struct pipe_screen *screen, const struct util_format_description *desc, int first_non_void) { - unsigned type; int i; if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT) return V_008F0C_BUF_DATA_FORMAT_10_11_11; assert(first_non_void >= 0); - type = desc->channel[first_non_void].type; - - if (type == UTIL_FORMAT_TYPE_FIXED) - return V_008F0C_BUF_DATA_FORMAT_INVALID; if (desc->nr_channels == 4 && desc->channel[0].size == 10 && @@ -1773,6 +1768,7 @@ static uint32_t si_translate_buffer_numformat(struct pipe_screen *screen, switch (desc->channel[first_non_void].type) { case UTIL_FORMAT_TYPE_SIGNED: + case UTIL_FORMAT_TYPE_FIXED: if (desc->channel[first_non_void].size >= 32 || desc->channel[first_non_void].pure_integer) return V_008F0C_BUF_NUM_FORMAT_SINT; @@ -3366,6 +3362,11 @@ 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->type == UTIL_FORMAT_TYPE_FIXED) { + if (desc->swizzle[3] == PIPE_SWIZZLE_1) + v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBX_32_FIXED << (4 * i); + else + v->fix_fetch |= (uint64_t)SI_FIX_FETCH_RGBA_32_FIXED << (4 * i); } else if (channel->size == 32 && !channel->pure_integer) { if (channel->type == UTIL_FORMAT_TYPE_SIGNED) { if (channel->normalized) { |