diff options
| -rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 13 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 16 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_render.c | 12 | ||||
| -rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 142 | 
4 files changed, 91 insertions, 92 deletions
| diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 48ec52d26c..cca11f8045 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -326,6 +326,17 @@ struct r300_vertex_element_state {      unsigned count;      struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; +    /* If (velem[i].src_format != hw_format[i]), the vertex buffer +     * referenced by this vertex element cannot be used for rendering and +     * its vertex data must be translated to hw_format[i]. */ +    enum pipe_format hw_format[PIPE_MAX_ATTRIBS]; +    unsigned hw_format_size[PIPE_MAX_ATTRIBS]; + +    /* This might mean two things: +     * - src_format != hw_format, as discussed above. +     * - src_offset % 4 != 0. */ +    boolean incompatible_layout; +      struct r300_vertex_stream_state vertex_stream;  }; @@ -434,6 +445,8 @@ struct r300_context {      int sprite_coord_enable;      /* Whether two-sided color selection is enabled (AKA light_twoside). */      boolean two_sided_color; +    /* Incompatible vertex buffer layout? (misaligned stride or buffer_offset) */ +    boolean incompatible_vb_layout;      /* upload managers */      struct u_upload_mgr *upload_vb; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index c329c0f30f..dd9bca88f1 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -821,19 +821,11 @@ void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)      struct pipe_vertex_element *velem = r300->velems->velem;      struct r300_buffer *buf;      int i; +    unsigned *hw_format_size = r300->velems->hw_format_size;      unsigned size1, size2, aos_count = r300->velems->count;      unsigned packet_size = (aos_count * 3 + 1) / 2;      CS_LOCALS(r300); -    for (i = 0; i < aos_count; i++) { -        if ((vbuf[velem[i].vertex_buffer_index].buffer_offset + velem[i].src_offset) % 4 != 0) { -            /* XXX We must align the buffer. */ -            assert(0); -            fprintf(stderr, "r300: Unaligned vertex buffer offsets aren't supported, aborting..\n"); -            abort(); -        } -    } -      BEGIN_CS(2 + packet_size + aos_count * 2);      OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size);      OUT_CS(aos_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0)); @@ -841,8 +833,8 @@ void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)      for (i = 0; i < aos_count - 1; i += 2) {          vb1 = &vbuf[velem[i].vertex_buffer_index];          vb2 = &vbuf[velem[i+1].vertex_buffer_index]; -        size1 = util_format_get_blocksize(velem[i].src_format); -        size2 = util_format_get_blocksize(velem[i+1].src_format); +        size1 = hw_format_size[i]; +        size2 = hw_format_size[i+1];          OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) |                 R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride)); @@ -852,7 +844,7 @@ void r300_emit_aos(struct r300_context* r300, int offset, boolean indexed)      if (aos_count & 1) {          vb1 = &vbuf[velem[i].vertex_buffer_index]; -        size1 = util_format_get_blocksize(velem[i].src_format); +        size1 = hw_format_size[i];          OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride));          OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 23caaa5473..80dea8be98 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -333,7 +333,7 @@ static void r300_emit_draw_arrays_immediate(struct r300_context *r300,      for (i = 0; i < vertex_element_count; i++) {          velem = &r300->velems->velem[i];          offset[i] = velem->src_offset / 4; -        size[i] = util_format_get_blocksize(velem->src_format) / 4; +        size[i] = r300->velems->hw_format_size[i] / 4;          vertex_size += size[i];          vbi = velem->vertex_buffer_index; @@ -610,6 +610,11 @@ static void r300_draw_range_elements(struct pipe_context* pipe,          return;      } +    if (r300->incompatible_vb_layout || +        r300->velems->incompatible_layout) { +        return; +    } +      if (!u_trim_pipe_prim(mode, &count)) {          return;      } @@ -704,6 +709,11 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,          return;      } +    if (r300->incompatible_vb_layout || +        r300->velems->incompatible_layout) { +        return; +    } +      if (!u_trim_pipe_prim(mode, &count)) {          return;      } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index cfec8ac2b7..d19563c18a 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -1167,15 +1167,15 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,      if (r300->screen->caps.has_tcl) {          /* HW TCL. */ -        /* Check if the stride is aligned to the size of DWORD. */ +        r300->incompatible_vb_layout = FALSE; + +        /* Check if the strides and offsets are aligned to the size of DWORD. */          for (i = 0; i < count; i++) {              if (buffers[i].buffer) { -                if (buffers[i].stride % 4 != 0) { -                    // XXX Shouldn't we align the buffer? -                    fprintf(stderr, "r300: set_vertex_buffers: " -                            "Unaligned buffer stride %i isn't supported.\n", -                            buffers[i].stride); -                    abort(); +                if (buffers[i].stride % 4 != 0 || +                    buffers[i].buffer_offset % 4 != 0) { +                    r300->incompatible_vb_layout = TRUE; +                    break;                  }              }          } @@ -1248,7 +1248,7 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)       * so PSC should just route stuff based on the vertex elements,       * and not on attrib information. */      for (i = 0; i < velems->count; i++) { -        format = velems->velem[i].src_format; +        format = velems->hw_format[i];          type = r300_translate_vertex_data_type(format);          if (type == R300_INVALID_FORMAT) { @@ -1280,12 +1280,15 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)      vstream->count = (i >> 1) + 1;  } +#define FORMAT_REPLACE(what, withwhat) \ +    case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break +  static void* r300_create_vertex_elements_state(struct pipe_context* pipe,                                                 unsigned count,                                                 const struct pipe_vertex_element* attribs)  {      struct r300_vertex_element_state *velems; -    unsigned i, size; +    unsigned i;      enum pipe_format *format;      assert(count <= PIPE_MAX_ATTRIBS); @@ -1293,88 +1296,69 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,      if (velems != NULL) {          velems->count = count;          memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count); +        velems->incompatible_layout = FALSE;          if (r300_screen(pipe->screen)->caps.has_tcl) { -            r300_vertex_psc(velems); - -            /* Check if the format is aligned to the size of DWORD. -             * We only care about the blocksizes of the formats since -             * swizzles are already set up. */ +            /* Set the best hw format in case the original format is not +             * supported by hw. */              for (i = 0; i < count; i++) { -                format = &velems->velem[i].src_format; +                velems->hw_format[i] = velems->velem[i].src_format; +                format = &velems->hw_format[i]; -                /* Replace some formats with their aligned counterparts, -                 * this is OK because we check for aligned strides too. */ +                /* This is basically the list of unsupported formats. +                 * For now we don't care about the alignment, that's going to +                 * be sorted out after the PSC setup. */                  switch (*format) { -                    /* Align to RGBA8. */ -                    case PIPE_FORMAT_R8_UNORM: -                    case PIPE_FORMAT_R8G8_UNORM: -                    case PIPE_FORMAT_R8G8B8_UNORM: -                        *format = PIPE_FORMAT_R8G8B8A8_UNORM; -                        continue; -                    case PIPE_FORMAT_R8_SNORM: -                    case PIPE_FORMAT_R8G8_SNORM: -                    case PIPE_FORMAT_R8G8B8_SNORM: -                        *format = PIPE_FORMAT_R8G8B8A8_SNORM; -                        continue; -                    case PIPE_FORMAT_R8_USCALED: -                    case PIPE_FORMAT_R8G8_USCALED: -                    case PIPE_FORMAT_R8G8B8_USCALED: -                        *format = PIPE_FORMAT_R8G8B8A8_USCALED; -                        continue; -                    case PIPE_FORMAT_R8_SSCALED: -                    case PIPE_FORMAT_R8G8_SSCALED: -                    case PIPE_FORMAT_R8G8B8_SSCALED: -                        *format = PIPE_FORMAT_R8G8B8A8_SSCALED; -                        continue; +                    FORMAT_REPLACE(R64_FLOAT,           R32_FLOAT); +                    FORMAT_REPLACE(R64G64_FLOAT,        R32G32_FLOAT); +                    FORMAT_REPLACE(R64G64B64_FLOAT,     R32G32B32_FLOAT); +                    FORMAT_REPLACE(R64G64B64A64_FLOAT,  R32G32B32A32_FLOAT); + +                    FORMAT_REPLACE(R32_UNORM,           R32_FLOAT); +                    FORMAT_REPLACE(R32G32_UNORM,        R32G32_FLOAT); +                    FORMAT_REPLACE(R32G32B32_UNORM,     R32G32B32_FLOAT); +                    FORMAT_REPLACE(R32G32B32A32_UNORM,  R32G32B32A32_FLOAT); + +                    FORMAT_REPLACE(R32_USCALED,         R32_FLOAT); +                    FORMAT_REPLACE(R32G32_USCALED,      R32G32_FLOAT); +                    FORMAT_REPLACE(R32G32B32_USCALED,   R32G32B32_FLOAT); +                    FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT); -                    /* Align to RG16. */ -                    case PIPE_FORMAT_R16_UNORM: -                        *format = PIPE_FORMAT_R16G16_UNORM; -                        continue; -                    case PIPE_FORMAT_R16_SNORM: -                        *format = PIPE_FORMAT_R16G16_SNORM; -                        continue; -                    case PIPE_FORMAT_R16_USCALED: -                        *format = PIPE_FORMAT_R16G16_USCALED; -                        continue; -                    case PIPE_FORMAT_R16_SSCALED: -                        *format = PIPE_FORMAT_R16G16_SSCALED; -                        continue; -                    case PIPE_FORMAT_R16_FLOAT: -                        *format = PIPE_FORMAT_R16G16_FLOAT; -                        continue; +                    FORMAT_REPLACE(R32_SNORM,           R32_FLOAT); +                    FORMAT_REPLACE(R32G32_SNORM,        R32G32_FLOAT); +                    FORMAT_REPLACE(R32G32B32_SNORM,     R32G32B32_FLOAT); +                    FORMAT_REPLACE(R32G32B32A32_SNORM,  R32G32B32A32_FLOAT); -                    /* Align to RGBA16. */ -                    case PIPE_FORMAT_R16G16B16_UNORM: -                        *format = PIPE_FORMAT_R16G16B16A16_UNORM; -                        continue; -                    case PIPE_FORMAT_R16G16B16_SNORM: -                        *format = PIPE_FORMAT_R16G16B16A16_SNORM; -                        continue; -                    case PIPE_FORMAT_R16G16B16_USCALED: -                        *format = PIPE_FORMAT_R16G16B16A16_USCALED; -                        continue; -                    case PIPE_FORMAT_R16G16B16_SSCALED: -                        *format = PIPE_FORMAT_R16G16B16A16_SSCALED; -                        continue; -                    case PIPE_FORMAT_R16G16B16_FLOAT: -                        *format = PIPE_FORMAT_R16G16B16A16_FLOAT; -                        continue; +                    FORMAT_REPLACE(R32_SSCALED,         R32_FLOAT); +                    FORMAT_REPLACE(R32G32_SSCALED,      R32G32_FLOAT); +                    FORMAT_REPLACE(R32G32B32_SSCALED,   R32G32B32_FLOAT); +                    FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT); + +                    FORMAT_REPLACE(R32_FIXED,           R32_FLOAT); +                    FORMAT_REPLACE(R32G32_FIXED,        R32G32_FLOAT); +                    FORMAT_REPLACE(R32G32B32_FIXED,     R32G32B32_FLOAT); +                    FORMAT_REPLACE(R32G32B32A32_FIXED,  R32G32B32A32_FLOAT);                      default:;                  } -                size = util_format_get_blocksize(*format); +                velems->incompatible_layout = +                        velems->incompatible_layout || +                        velems->velem[i].src_format != velems->hw_format[i] || +                        velems->velem[i].src_offset % 4 != 0; +            } -                if (size % 4 != 0) { -                    /* XXX Shouldn't we align the format? */ -                    fprintf(stderr, "r300_create_vertex_elements_state: " -                            "Unaligned format %s:%i isn't supported\n", -                            util_format_short_name(*format), size); -                    assert(0); -                    abort(); -                } +            /* Now setup PSC. +             * The unused components will be replaced by (..., 0, 1). */ +            r300_vertex_psc(velems); + +            /* Align the formats to the size of DWORD. +             * We only care about the blocksizes of the formats since +             * swizzles are already set up. */ +            for (i = 0; i < count; i++) { +                /* This is OK because we check for aligned strides too. */ +                velems->hw_format_size[i] = +                    align(util_format_get_blocksize(velems->hw_format[i]), 4);              }          }      } | 
