Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "swrast/swrast.h"
  2. #include "main/renderbuffer.h"
  3. #include "main/texobj.h"
  4. #include "main/teximage.h"
  5. #include "main/mipmap.h"
  6. #include "drivers/common/meta.h"
  7. #include "brw_context.h"
  8. #include "intel_buffer_objects.h"
  9. #include "intel_mipmap_tree.h"
  10. #include "intel_tex.h"
  11. #include "intel_fbo.h"
  12.  
  13. #define FILE_DEBUG_FLAG DEBUG_TEXTURE
  14.  
  15. static struct gl_texture_image *
  16. intelNewTextureImage(struct gl_context * ctx)
  17. {
  18.    DBG("%s\n", __func__);
  19.    (void) ctx;
  20.    return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image);
  21. }
  22.  
  23. static void
  24. intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
  25. {
  26.    /* nothing special (yet) for intel_texture_image */
  27.    _mesa_delete_texture_image(ctx, img);
  28. }
  29.  
  30.  
  31. static struct gl_texture_object *
  32. intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
  33. {
  34.    struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
  35.  
  36.    (void) ctx;
  37.  
  38.    DBG("%s\n", __func__);
  39.  
  40.    if (obj == NULL)
  41.       return NULL;
  42.  
  43.    _mesa_initialize_texture_object(ctx, &obj->base, name, target);
  44.  
  45.    obj->needs_validate = true;
  46.  
  47.    return &obj->base;
  48. }
  49.  
  50. static void
  51. intelDeleteTextureObject(struct gl_context *ctx,
  52.                          struct gl_texture_object *texObj)
  53. {
  54.    struct intel_texture_object *intelObj = intel_texture_object(texObj);
  55.  
  56.    intel_miptree_release(&intelObj->mt);
  57.    _mesa_delete_texture_object(ctx, texObj);
  58. }
  59.  
  60. static GLboolean
  61. intel_alloc_texture_image_buffer(struct gl_context *ctx,
  62.                                  struct gl_texture_image *image)
  63. {
  64.    struct brw_context *brw = brw_context(ctx);
  65.    struct intel_texture_image *intel_image = intel_texture_image(image);
  66.    struct gl_texture_object *texobj = image->TexObject;
  67.    struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
  68.  
  69.    assert(image->Border == 0);
  70.  
  71.    /* Quantize sample count */
  72.    if (image->NumSamples) {
  73.       image->NumSamples = intel_quantize_num_samples(brw->intelScreen, image->NumSamples);
  74.       if (!image->NumSamples)
  75.          return false;
  76.    }
  77.  
  78.    /* Because the driver uses AllocTextureImageBuffer() internally, it may end
  79.     * up mismatched with FreeTextureImageBuffer(), but that is safe to call
  80.     * multiple times.
  81.     */
  82.    ctx->Driver.FreeTextureImageBuffer(ctx, image);
  83.  
  84.    if (!_swrast_init_texture_image(image))
  85.       return false;
  86.  
  87.    if (intel_texobj->mt &&
  88.        intel_miptree_match_image(intel_texobj->mt, image)) {
  89.       intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
  90.       DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n",
  91.           __func__, texobj, image->Level,
  92.           image->Width, image->Height, image->Depth, intel_texobj->mt);
  93.    } else {
  94.       intel_image->mt = intel_miptree_create_for_teximage(brw, intel_texobj,
  95.                                                           intel_image,
  96.                                                           false);
  97.  
  98.       /* Even if the object currently has a mipmap tree associated
  99.        * with it, this one is a more likely candidate to represent the
  100.        * whole object since our level didn't fit what was there
  101.        * before, and any lower levels would fit into our miptree.
  102.        */
  103.       intel_miptree_reference(&intel_texobj->mt, intel_image->mt);
  104.  
  105.       DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n",
  106.           __func__, texobj, image->Level,
  107.           image->Width, image->Height, image->Depth, intel_image->mt);
  108.    }
  109.  
  110.    intel_texobj->needs_validate = true;
  111.  
  112.    return true;
  113. }
  114.  
  115. /**
  116.  * ctx->Driver.AllocTextureStorage() handler.
  117.  *
  118.  * Compare this to _mesa_AllocTextureStorage_sw, which would call into
  119.  * intel_alloc_texture_image_buffer() above.
  120.  */
  121. static GLboolean
  122. intel_alloc_texture_storage(struct gl_context *ctx,
  123.                             struct gl_texture_object *texobj,
  124.                             GLsizei levels, GLsizei width,
  125.                             GLsizei height, GLsizei depth)
  126. {
  127.    struct brw_context *brw = brw_context(ctx);
  128.    struct intel_texture_object *intel_texobj = intel_texture_object(texobj);
  129.    struct gl_texture_image *first_image = texobj->Image[0][0];
  130.    int num_samples = intel_quantize_num_samples(brw->intelScreen,
  131.                                                 first_image->NumSamples);
  132.    const int numFaces = _mesa_num_tex_faces(texobj->Target);
  133.    int face;
  134.    int level;
  135.  
  136.    /* If the object's current miptree doesn't match what we need, make a new
  137.     * one.
  138.     */
  139.    if (!intel_texobj->mt ||
  140.        !intel_miptree_match_image(intel_texobj->mt, first_image) ||
  141.        intel_texobj->mt->last_level != levels - 1) {
  142.       intel_miptree_release(&intel_texobj->mt);
  143.       intel_texobj->mt = intel_miptree_create(brw, texobj->Target,
  144.                                               first_image->TexFormat,
  145.                                               0, levels - 1,
  146.                                               width, height, depth,
  147.                                               false, /* expect_accelerated */
  148.                                               num_samples,
  149.                                               INTEL_MIPTREE_TILING_ANY,
  150.                                               false);
  151.  
  152.       if (intel_texobj->mt == NULL) {
  153.          return false;
  154.       }
  155.    }
  156.  
  157.    for (face = 0; face < numFaces; face++) {
  158.       for (level = 0; level < levels; level++) {
  159.          struct gl_texture_image *image = texobj->Image[face][level];
  160.          struct intel_texture_image *intel_image = intel_texture_image(image);
  161.  
  162.          image->NumSamples = num_samples;
  163.  
  164.          _swrast_free_texture_image_buffer(ctx, image);
  165.          if (!_swrast_init_texture_image(image))
  166.             return false;
  167.  
  168.          intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
  169.       }
  170.    }
  171.  
  172.    /* The miptree is in a validated state, so no need to check later. */
  173.    intel_texobj->needs_validate = false;
  174.    intel_texobj->validated_first_level = 0;
  175.    intel_texobj->validated_last_level = levels - 1;
  176.    intel_texobj->_Format = intel_texobj->mt->format;
  177.  
  178.    return true;
  179. }
  180.  
  181.  
  182. static void
  183. intel_free_texture_image_buffer(struct gl_context * ctx,
  184.                                 struct gl_texture_image *texImage)
  185. {
  186.    struct intel_texture_image *intelImage = intel_texture_image(texImage);
  187.  
  188.    DBG("%s\n", __func__);
  189.  
  190.    intel_miptree_release(&intelImage->mt);
  191.  
  192.    _swrast_free_texture_image_buffer(ctx, texImage);
  193. }
  194.  
  195. /**
  196.  * Map texture memory/buffer into user space.
  197.  * Note: the region of interest parameters are ignored here.
  198.  * \param mode  bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT
  199.  * \param mapOut  returns start of mapping of region of interest
  200.  * \param rowStrideOut  returns row stride in bytes
  201.  */
  202. static void
  203. intel_map_texture_image(struct gl_context *ctx,
  204.                         struct gl_texture_image *tex_image,
  205.                         GLuint slice,
  206.                         GLuint x, GLuint y, GLuint w, GLuint h,
  207.                         GLbitfield mode,
  208.                         GLubyte **map,
  209.                         GLint *out_stride)
  210. {
  211.    struct brw_context *brw = brw_context(ctx);
  212.    struct intel_texture_image *intel_image = intel_texture_image(tex_image);
  213.    struct intel_mipmap_tree *mt = intel_image->mt;
  214.    ptrdiff_t stride;
  215.  
  216.    /* Our texture data is always stored in a miptree. */
  217.    assert(mt);
  218.  
  219.    /* Check that our caller wasn't confused about how to map a 1D texture. */
  220.    assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY ||
  221.           h == 1);
  222.  
  223.    /* intel_miptree_map operates on a unified "slice" number that references the
  224.     * cube face, since it's all just slices to the miptree code.
  225.     */
  226.    if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
  227.       slice = tex_image->Face;
  228.  
  229.    intel_miptree_map(brw, mt,
  230.                      tex_image->Level + tex_image->TexObject->MinLevel,
  231.                      slice + tex_image->TexObject->MinLayer,
  232.                      x, y, w, h, mode,
  233.                      (void **)map, &stride);
  234.  
  235.    *out_stride = stride;
  236. }
  237.  
  238. static void
  239. intel_unmap_texture_image(struct gl_context *ctx,
  240.                           struct gl_texture_image *tex_image, GLuint slice)
  241. {
  242.    struct brw_context *brw = brw_context(ctx);
  243.    struct intel_texture_image *intel_image = intel_texture_image(tex_image);
  244.    struct intel_mipmap_tree *mt = intel_image->mt;
  245.  
  246.    if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP)
  247.       slice = tex_image->Face;
  248.  
  249.    intel_miptree_unmap(brw, mt,
  250.          tex_image->Level + tex_image->TexObject->MinLevel,
  251.          slice + tex_image->TexObject->MinLayer);
  252. }
  253.  
  254. static GLboolean
  255. intel_texture_view(struct gl_context *ctx,
  256.                    struct gl_texture_object *texObj,
  257.                    struct gl_texture_object *origTexObj)
  258. {
  259.    struct brw_context *brw = brw_context(ctx);
  260.    struct intel_texture_object *intel_tex = intel_texture_object(texObj);
  261.    struct intel_texture_object *intel_orig_tex = intel_texture_object(origTexObj);
  262.  
  263.    assert(intel_orig_tex->mt);
  264.    intel_miptree_reference(&intel_tex->mt, intel_orig_tex->mt);
  265.  
  266.    /* Since we can only make views of immutable-format textures,
  267.     * we can assume that everything is in origTexObj's miptree.
  268.     *
  269.     * Mesa core has already made us a copy of all the teximage objects,
  270.     * except it hasn't copied our mt pointers, etc.
  271.     */
  272.    const int numFaces = _mesa_num_tex_faces(texObj->Target);
  273.    const int numLevels = texObj->NumLevels;
  274.  
  275.    int face;
  276.    int level;
  277.  
  278.    for (face = 0; face < numFaces; face++) {
  279.       for (level = 0; level < numLevels; level++) {
  280.          struct gl_texture_image *image = texObj->Image[face][level];
  281.          struct intel_texture_image *intel_image = intel_texture_image(image);
  282.  
  283.          intel_miptree_reference(&intel_image->mt, intel_orig_tex->mt);
  284.       }
  285.    }
  286.  
  287.    /* The miptree is in a validated state, so no need to check later. */
  288.    intel_tex->needs_validate = false;
  289.    intel_tex->validated_first_level = 0;
  290.    intel_tex->validated_last_level = numLevels - 1;
  291.  
  292.    /* Set the validated texture format, with the same adjustments that
  293.     * would have been applied to determine the underlying texture's
  294.     * mt->format.
  295.     */
  296.    intel_tex->_Format = intel_depth_format_for_depthstencil_format(
  297.          intel_lower_compressed_format(brw, texObj->Image[0][0]->TexFormat));
  298.  
  299.    return GL_TRUE;
  300. }
  301.  
  302. static bool
  303. intel_set_texture_storage_for_buffer_object(struct gl_context *ctx,
  304.                                             struct gl_texture_object *tex_obj,
  305.                                             struct gl_buffer_object *buffer_obj,
  306.                                             uint32_t buffer_offset,
  307.                                             uint32_t row_stride,
  308.                                             bool read_only)
  309. {
  310.    struct brw_context *brw = brw_context(ctx);
  311.    struct intel_texture_object *intel_texobj = intel_texture_object(tex_obj);
  312.    struct gl_texture_image *image = tex_obj->Image[0][0];
  313.    struct intel_texture_image *intel_image = intel_texture_image(image);
  314.    struct intel_buffer_object *intel_buffer_obj = intel_buffer_object(buffer_obj);
  315.  
  316.    if (!read_only) {
  317.       /* Renderbuffers have the restriction that the buffer offset and
  318.        * surface pitch must be a multiple of the element size.  If it's
  319.        * not, we have to fail and fall back to software.
  320.        */
  321.       int cpp = _mesa_get_format_bytes(image->TexFormat);
  322.       if (buffer_offset % cpp || row_stride % cpp) {
  323.          perf_debug("Bad PBO alignment; fallback to CPU mapping\n");
  324.          return false;
  325.       }
  326.  
  327.       if (!brw->format_supported_as_render_target[image->TexFormat]) {
  328.          perf_debug("Non-renderable PBO format; fallback to CPU mapping\n");
  329.          return false;
  330.       }
  331.    }
  332.  
  333.    assert(intel_texobj->mt == NULL);
  334.  
  335.    drm_intel_bo *bo = intel_bufferobj_buffer(brw, intel_buffer_obj,
  336.                                              buffer_offset,
  337.                                              row_stride * image->Height);
  338.    intel_texobj->mt =
  339.       intel_miptree_create_for_bo(brw, bo,
  340.                                   image->TexFormat,
  341.                                   buffer_offset,
  342.                                   image->Width, image->Height, image->Depth,
  343.                                   row_stride,
  344.                                   false /*disable_aux_buffers*/);
  345.    if (!intel_texobj->mt)
  346.       return false;
  347.  
  348.    if (!_swrast_init_texture_image(image))
  349.       return false;
  350.  
  351.    intel_miptree_reference(&intel_image->mt, intel_texobj->mt);
  352.  
  353.    /* The miptree is in a validated state, so no need to check later. */
  354.    intel_texobj->needs_validate = false;
  355.    intel_texobj->validated_first_level = 0;
  356.    intel_texobj->validated_last_level = 0;
  357.    intel_texobj->_Format = intel_texobj->mt->format;
  358.  
  359.    return true;
  360. }
  361.  
  362. void
  363. intelInitTextureFuncs(struct dd_function_table *functions)
  364. {
  365.    functions->NewTextureObject = intelNewTextureObject;
  366.    functions->NewTextureImage = intelNewTextureImage;
  367.    functions->DeleteTextureImage = intelDeleteTextureImage;
  368.    functions->DeleteTexture = intelDeleteTextureObject;
  369.    functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer;
  370.    functions->FreeTextureImageBuffer = intel_free_texture_image_buffer;
  371.    functions->AllocTextureStorage = intel_alloc_texture_storage;
  372.    functions->MapTextureImage = intel_map_texture_image;
  373.    functions->UnmapTextureImage = intel_unmap_texture_image;
  374.    functions->TextureView = intel_texture_view;
  375.    functions->SetTextureStorageForBufferObject =
  376.       intel_set_texture_storage_for_buffer_object;
  377. }
  378.