Merge branch '7.8'
[mesa.git] / src / gallium / state_trackers / python / st_sample.c
index 7765df3c4a4c6aa0cf2b9937eeaf4f6d67110bd4..25bfbf1ab73d5991ede74566fa9394ae6025ebcb 100644 (file)
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
 #include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
+#include "util/u_inlines.h"
+#include "util/u_format.h"
 #include "util/u_tile.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
 
+#include "st_device.h"
 #include "st_sample.h"
 
 
@@ -48,7 +50,7 @@ static uint32_t st_random(void) {
 
    seed = UINT64_C(134775813) * seed + UINT64_C(1);
    
-   return (uint16_t)(seed >> 32); 
+   return (uint32_t)(seed >> 32);
 }
 
 
@@ -422,7 +424,6 @@ dxt5_rgba_data[] = {
 
 static INLINE void 
 st_sample_dxt_pixel_block(enum pipe_format format, 
-                          const struct pipe_format_block *block,
                           uint8_t *raw,
                           float *rgba, unsigned rgba_stride, 
                           unsigned w, unsigned h)
@@ -451,6 +452,7 @@ st_sample_dxt_pixel_block(enum pipe_format format,
       break;
    default:
       assert(0);
+      return;
    }
    
    i = st_random() % n;
@@ -460,33 +462,50 @@ st_sample_dxt_pixel_block(enum pipe_format format,
          for(ch = 0; ch < 4; ++ch)
             rgba[y*rgba_stride + x*4 + ch] = (float)(data[i].rgba[y*4*4 + x*4 + ch])/255.0f;
    
-   memcpy(raw, data[i].raw, block->size);
+   memcpy(raw, data[i].raw, util_format_get_blocksize(format));
 }
 
 
 static INLINE void 
 st_sample_generic_pixel_block(enum pipe_format format, 
-                              const struct pipe_format_block *block,
                               uint8_t *raw,
                               float *rgba, unsigned rgba_stride,
-                              unsigned w, unsigned h)
+                              unsigned w, unsigned h,
+                              boolean norm)
 {
    unsigned i;
    unsigned x, y, ch;
+   int blocksize = util_format_get_blocksize(format);
    
-   for(i = 0; i < block->size; ++i)
-      raw[i] = (uint8_t)st_random();
-   
-   
-   pipe_tile_raw_to_rgba(format,
-                         raw,
-                         w, h,
-                         rgba, rgba_stride);
-   if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV) {
-      for(y = 0; y < h; ++y) {
-         for(x = 0; x < w; ++x) {
-            for(ch = 0; ch < 4; ++ch) {
+   if (norm) {
+      for (y = 0; y < h; ++y) {
+         for (x = 0; x < w; ++x) {
+            for (ch = 0; ch < 4; ++ch) {
+               unsigned offset = y*rgba_stride + x*4 + ch;
+               rgba[offset] = (st_random() & 0xff) / (double)0xff;
+            }
+         }
+      }
+
+      util_format_write_4f(format,
+                           rgba, rgba_stride * sizeof(float),
+                           raw, util_format_get_stride(format, w),
+                           0, 0, w, h);
+
+   } else {
+      for (i = 0; i < blocksize; ++i)
+         raw[i] = (uint8_t)st_random();
+   }
+
+   util_format_read_4f(format,
+                       rgba, rgba_stride * sizeof(float),
+                       raw, util_format_get_stride(format, w),
+                       0, 0, w, h);
+
+   if (format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV) {
+      for (y = 0; y < h; ++y) {
+         for (x = 0; x < w; ++x) {
+            for (ch = 0; ch < 4; ++ch) {
                unsigned offset = y*rgba_stride + x*4 + ch;
                rgba[offset] = CLAMP(rgba[offset], 0.0f, 1.0f);
             }
@@ -501,49 +520,76 @@ st_sample_generic_pixel_block(enum pipe_format format,
  */
 void 
 st_sample_pixel_block(enum pipe_format format,
-                      const struct pipe_format_block *block,
                       void *raw,
                       float *rgba, unsigned rgba_stride,
-                      unsigned w, unsigned h)
+                      unsigned w, unsigned h,
+                      boolean norm)
 {
    switch(format) {
    case PIPE_FORMAT_DXT1_RGB:
    case PIPE_FORMAT_DXT1_RGBA:
    case PIPE_FORMAT_DXT3_RGBA:
    case PIPE_FORMAT_DXT5_RGBA:
-      st_sample_dxt_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+      st_sample_dxt_pixel_block(format, raw, rgba, rgba_stride, w, h);
       break;
 
    default:
-      st_sample_generic_pixel_block(format, block, raw, rgba, rgba_stride, w, h);
+      st_sample_generic_pixel_block(format, raw, rgba, rgba_stride, w, h, norm);
       break;
    }
 }
 
 
 void
-st_sample_surface(struct pipe_surface *surface, float *rgba) 
+st_sample_surface(struct pipe_context *pipe,
+                  struct st_surface *surface,
+                  float *rgba,
+                  boolean norm)
 {
-   const struct pipe_format_block *block = &surface->block;
-   unsigned rgba_stride = surface->width*4;
+   struct pipe_resource *texture = surface->texture;
+   unsigned width = u_minify(texture->width0, surface->level);
+   unsigned height = u_minify(texture->height0, surface->level);
+   uint rgba_stride = width * 4;
+   struct pipe_transfer *transfer;
    void *raw;
-   unsigned x, y;
 
-   raw = pipe_surface_map(surface, PIPE_BUFFER_USAGE_CPU_READ);
-   if(!raw)
+   transfer = pipe_get_transfer(pipe,
+                                surface->texture,
+                                surface->face,
+                                surface->level,
+                                surface->zslice,
+                                PIPE_TRANSFER_WRITE,
+                                0, 0,
+                                width,
+                                height);
+   if (!transfer)
       return;
 
-   for (y = 0; y < surface->nblocksy; ++y) {
-      for(x = 0; x < surface->nblocksx; ++x) {
-         st_sample_pixel_block(surface->format,
-                               block,
-                               (uint8_t*)raw + y*surface->stride + x*block->size, 
-                               rgba + y*block->height*rgba_stride + x*block->width*4,
-                               rgba_stride,
-                               MIN2(block->width, surface->width - x*block->width), 
-                               MIN2(block->height, surface->height - y*block->height));
-       }
+   raw = pipe->transfer_map(pipe, transfer);
+   if (raw) {
+      enum pipe_format format = texture->format;
+      uint x, y;
+      int nblocksx = util_format_get_nblocksx(format, width);
+      int nblocksy = util_format_get_nblocksy(format, height);
+      int blockwidth = util_format_get_blockwidth(format);
+      int blockheight = util_format_get_blockheight(format);
+      int blocksize = util_format_get_blocksize(format);
+
+
+      for (y = 0; y < nblocksy; ++y) {
+         for (x = 0; x < nblocksx; ++x) {
+            st_sample_pixel_block(format,
+                                  (uint8_t *) raw + y * transfer->stride + x * blocksize,
+                                  rgba + y * blockheight * rgba_stride + x * blockwidth * 4,
+                                  rgba_stride,
+                                  MIN2(blockwidth, width - x*blockwidth),
+                                  MIN2(blockheight, height - y*blockheight),
+                                  norm);
+         }
+      }
+
+      pipe->transfer_unmap(pipe, transfer);
    }
-   
-   pipe_surface_unmap(surface);
+
+   pipe->transfer_destroy(pipe, transfer);
 }