radeonsi: implement GL_FIXED vertex format
authorMarek Olšák <marek.olsak@amd.com>
Fri, 6 Jan 2017 00:16:44 +0000 (01:16 +0100)
committerMarek Olšák <marek.olsak@amd.com>
Mon, 16 Jan 2017 17:07:08 +0000 (18:07 +0100)
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/gallium/drivers/radeonsi/si_shader.c
src/gallium/drivers/radeonsi/si_shader.h
src/gallium/drivers/radeonsi/si_state.c

index 840b3790f045843fdad9afb1bf7f0fda93d5b2b4..f404273243f2bf5e336c5ad38c47a4d8c80c7b36 100644 (file)
@@ -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],
index 5e554d9afe3c6aa2fb27b476b7aaf0f77a1d16ae..758403518f65b39b7c0e9d5f53ebbc1bd83a7ff2 100644 (file)
@@ -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;
index c8d1099421cfa0350d629ad2a17c733857c2ff2c..865a75dbe64965a4ff7f603a7cc0e03a416e4d72 100644 (file)
@@ -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) {