svga: check return value of define_query_vgpu{9,10}
[mesa.git] / src / gallium / drivers / svga / svga_state_constants.c
index c93d2a5e56558ef5d18cef6d8771be2c44c1422e..2c1b7048673ece9546b0699967a67cb064032178 100644 (file)
  * \return number of float[4] constants put into the 'dest' buffer
  */
 static unsigned
-svga_get_extra_constants_common(struct svga_context *svga,
+svga_get_extra_constants_common(const struct svga_context *svga,
                                 const struct svga_shader_variant *variant,
-                                unsigned shader, float *dest)
+                                enum pipe_shader_type shader, float *dest)
 {
    uint32_t *dest_u = (uint32_t *) dest;  // uint version of dest
    unsigned i;
    unsigned count = 0;
 
    for (i = 0; i < variant->key.num_textures; i++) {
-      struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i];
+      const struct pipe_sampler_view *sv = svga->curr.sampler_views[shader][i];
       if (sv) {
-         struct pipe_resource *tex = sv->texture;
+         const struct pipe_resource *tex = sv->texture;
          /* Scaling factors needed for handling unnormalized texture coordinates
           * for texture rectangles.
           */
@@ -82,10 +82,10 @@ svga_get_extra_constants_common(struct svga_context *svga,
             /* debug/sanity check */
             assert(variant->key.tex[i].width_height_idx == count);
 
-            *dest++ = 1.0 / (float)tex->width0;
-            *dest++ = 1.0 / (float)tex->height0;
-            *dest++ = 1.0;
-            *dest++ = 1.0;
+            *dest++ = 1.0f / (float) tex->width0;
+            *dest++ = 1.0f / (float) tex->height0;
+            *dest++ = 1.0f;
+            *dest++ = 1.0f;
 
             count++;
          }
@@ -114,7 +114,7 @@ svga_get_extra_constants_common(struct svga_context *svga,
  * \return number of float[4] constants put into the dest buffer
  */
 static unsigned
-svga_get_extra_fs_constants(struct svga_context *svga, float *dest)
+svga_get_extra_fs_constants(const struct svga_context *svga, float *dest)
 {
    const struct svga_shader_variant *variant = svga->state.hw_draw.fs;
    unsigned count = 0;
@@ -133,7 +133,7 @@ svga_get_extra_fs_constants(struct svga_context *svga, float *dest)
  * will be returned in 'dest'.
  */
 static unsigned
-svga_get_prescale_constants(struct svga_context *svga, float **dest)
+svga_get_prescale_constants(const struct svga_context *svga, float **dest)
 {
    memcpy(*dest, svga->state.hw_clear.prescale.scale, 4 * sizeof(float));
    *dest += 4;
@@ -148,9 +148,9 @@ svga_get_prescale_constants(struct svga_context *svga, float **dest)
  * Emit extra constants needed for point sprite emulation.
  */
 static unsigned
-svga_get_pt_sprite_constants(struct svga_context *svga, float **dest)
+svga_get_pt_sprite_constants(const struct svga_context *svga, float **dest)
 {
-   struct svga_screen *screen = svga_screen(svga->pipe.screen);
+   const struct svga_screen *screen = svga_screen(svga->pipe.screen);
    float *dst = *dest;
 
    dst[0] = 1.0 / (svga->curr.viewport.scale[0] * 2);
@@ -166,7 +166,7 @@ svga_get_pt_sprite_constants(struct svga_context *svga, float **dest)
  * by '*dest'. The updated buffer pointer will be returned in 'dest'.
  */
 static unsigned
-svga_get_clip_plane_constants(struct svga_context *svga,
+svga_get_clip_plane_constants(const struct svga_context *svga,
                               const struct svga_shader_variant *variant,
                               float **dest)
 {
@@ -195,7 +195,7 @@ svga_get_clip_plane_constants(struct svga_context *svga,
  * \return number of float[4] constants put into the dest buffer
  */
 static unsigned
-svga_get_extra_vs_constants(struct svga_context *svga, float *dest)
+svga_get_extra_vs_constants(const struct svga_context *svga, float *dest)
 {
    const struct svga_shader_variant *variant = svga->state.hw_draw.vs;
    unsigned count = 0;
@@ -233,7 +233,7 @@ svga_get_extra_vs_constants(struct svga_context *svga, float *dest)
  * to by 'dest'.
  */
 static unsigned
-svga_get_extra_gs_constants(struct svga_context *svga, float *dest)
+svga_get_extra_gs_constants(const struct svga_context *svga, float *dest)
 {
    const struct svga_shader_variant *variant = svga->state.hw_draw.gs;
    unsigned count = 0;
@@ -264,48 +264,6 @@ svga_get_extra_gs_constants(struct svga_context *svga, float *dest)
    return count;
 }
 
-/**
- * Check and emit one shader constant register.
- * \param shader  PIPE_SHADER_FRAGMENT or PIPE_SHADER_VERTEX
- * \param i  which float[4] constant to change
- * \param value  the new float[4] value
- */
-static enum pipe_error
-emit_const(struct svga_context *svga, unsigned shader, unsigned i,
-           const float *value)
-{
-   enum pipe_error ret = PIPE_OK;
-
-   assert(shader < PIPE_SHADER_TYPES);
-   assert(i < SVGA3D_CONSTREG_MAX);
-   assert(!svga_have_vgpu10(svga));
-
-   if (memcmp(svga->state.hw_draw.cb[shader][i], value,
-              4 * sizeof(float)) != 0) {
-      if (SVGA_DEBUG & DEBUG_CONSTS)
-         debug_printf("%s %s %u: %f %f %f %f\n",
-                      __FUNCTION__,
-                      shader == PIPE_SHADER_VERTEX ? "VERT" : "FRAG",
-                      i,
-                      value[0],
-                      value[1],
-                      value[2],
-                      value[3]);
-
-      ret = SVGA3D_SetShaderConst( svga->swc,
-                                   i,
-                                   svga_shader_type(shader),
-                                   SVGA3D_CONST_TYPE_FLOAT,
-                                   value );
-      if (ret != PIPE_OK)
-         return ret;
-
-      memcpy(svga->state.hw_draw.cb[shader][i], value, 4 * sizeof(float));
-   }
-
-   return ret;
-}
-
 
 /*
  * Check and emit a range of shader constant registers, trying to coalesce
@@ -314,7 +272,7 @@ emit_const(struct svga_context *svga, unsigned shader, unsigned i,
  */
 static enum pipe_error
 emit_const_range(struct svga_context *svga,
-                 unsigned shader,
+                 enum pipe_shader_type shader,
                  unsigned offset,
                  unsigned count,
                  const float (*values)[4])
@@ -420,6 +378,9 @@ emit_const_range(struct svga_context *svga,
                 (j - i) * 4 * sizeof(float));
 
          i = j + 1;
+
+         svga->hud.num_const_updates++;
+
       } else {
          ++i;
       }
@@ -434,14 +395,12 @@ emit_const_range(struct svga_context *svga,
  * On VGPU10, emit_consts_vgpu10 is used instead.
  */
 static enum pipe_error
-emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
+emit_consts_vgpu9(struct svga_context *svga, enum pipe_shader_type shader)
 {
    const struct pipe_constant_buffer *cbuf;
-   struct svga_screen *ss = svga_screen(svga->pipe.screen);
    struct pipe_transfer *transfer = NULL;
    unsigned count;
    const float (*data)[4] = NULL;
-   unsigned i;
    enum pipe_error ret = PIPE_OK;
    const unsigned offset = 0;
 
@@ -459,29 +418,18 @@ emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
       data = (const float (*)[4])
          pipe_buffer_map(&svga->pipe, svga->curr.constbufs[shader][0].buffer,
                          PIPE_TRANSFER_READ, &transfer);
-      if (data == NULL) {
+      if (!data) {
          return PIPE_ERROR_OUT_OF_MEMORY;
       }
 
       /* sanity check */
-      assert(cbuf->buffer->width0 >=
-             cbuf->buffer_size);
+      assert(cbuf->buffer->width0 >= cbuf->buffer_size);
 
       /* Use/apply the constant buffer size and offsets here */
       count = cbuf->buffer_size / (4 * sizeof(float));
       data += cbuf->buffer_offset / (4 * sizeof(float));
 
-      if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) {
-         ret = emit_const_range( svga, shader, offset, count, data );
-      }
-      else {
-         for (i = 0; i < count; i++) {
-            ret = emit_const( svga, shader, offset + i, data[i] );
-            if (ret != PIPE_OK) {
-               break;
-            }
-         }
-      }
+      ret = emit_const_range( svga, shader, offset, count, data );
 
       pipe_buffer_unmap(&svga->pipe, transfer);
 
@@ -495,7 +443,7 @@ emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
       const struct svga_shader_variant *variant = NULL;
       unsigned offset;
       float extras[MAX_EXTRA_CONSTS][4];
-      unsigned count, i;
+      unsigned count;
 
       switch (shader) {
       case PIPE_SHADER_VERTEX:
@@ -513,20 +461,11 @@ emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
 
       assert(variant);
       offset = variant->shader->info.file_max[TGSI_FILE_CONSTANT] + 1;
-      assert(count <= Elements(extras));
+      assert(count <= ARRAY_SIZE(extras));
 
       if (count > 0) {
-         if (ss->hw_version >= SVGA3D_HWVERSION_WS8_B1) {
-            ret = emit_const_range(svga, shader, offset, count,
-                                   (const float (*) [4])extras);
-         }
-         else {
-            for (i = 0; i < count; i++) {
-               ret = emit_const(svga, shader, offset + i, extras[i]);
-               if (ret != PIPE_OK)
-                  return ret;
-            }
-         }
+         ret = emit_const_range(svga, shader, offset, count,
+                                (const float (*) [4])extras);
       }
    }
 
@@ -536,7 +475,7 @@ emit_consts_vgpu9(struct svga_context *svga, unsigned shader)
 
 
 static enum pipe_error
-emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
+emit_constbuf_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
 {
    const struct pipe_constant_buffer *cbuf;
    struct pipe_resource *dst_buffer = NULL;
@@ -549,12 +488,7 @@ emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
    void *src_map = NULL, *dst_map;
    unsigned offset;
    const struct svga_shader_variant *variant;
-
-   assert(shader == PIPE_SHADER_VERTEX ||
-          shader == PIPE_SHADER_GEOMETRY ||
-          shader == PIPE_SHADER_FRAGMENT);
-
-   cbuf = &svga->curr.constbufs[shader][0];
+   unsigned alloc_buf_size;
 
    switch (shader) {
    case PIPE_SHADER_VERTEX:
@@ -579,6 +513,8 @@ emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
 
    assert(variant);
 
+   cbuf = &svga->curr.constbufs[shader][0];
+
    /* Compute extra constants size and offset in bytes */
    extra_size = extra_count * 4 * sizeof(float);
    extra_offset = 4 * sizeof(float) * variant->extra_const_start;
@@ -613,7 +549,17 @@ emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
     */
    new_buf_size = align(new_buf_size, 16);
 
-   u_upload_alloc(svga->const0_upload, 0, new_buf_size, &offset,
+   /* Constant buffer size in the upload buffer must be in multiples of 256.
+    * In order to maximize the chance of merging the upload buffer chunks
+    * when svga_buffer_add_range() is called,
+    * the allocate buffer size needs to be in multiples of 256 as well.
+    * Otherwise, since there is gap between each dirty range of the upload buffer,
+    * each dirty range will end up in its own UPDATE_GB_IMAGE command.
+    */
+   alloc_buf_size = align(new_buf_size, CONST0_UPLOAD_ALIGNMENT);
+
+   u_upload_alloc(svga->const0_upload, 0, alloc_buf_size,
+                  CONST0_UPLOAD_ALIGNMENT, &offset,
                   &dst_buffer, &dst_map);
    if (!dst_map) {
       if (src_map)
@@ -630,15 +576,30 @@ emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
       assert(extra_offset + extra_size <= new_buf_size);
       memcpy((char *) dst_map + extra_offset, extras, extra_size);
    }
-   u_upload_unmap(svga->const0_upload);
 
-   /* Issue the SetSingleConstantBuffer command */
-   dst_handle = svga_buffer_handle(svga, dst_buffer);
-   if (!dst_handle) {
-      pipe_resource_reference(&dst_buffer, NULL);
-      return PIPE_ERROR_OUT_OF_MEMORY;
+   /* Get winsys handle for the constant buffer */
+   if (svga->state.hw_draw.const0_buffer == dst_buffer &&
+       svga->state.hw_draw.const0_handle) {
+      /* re-reference already mapped buffer */
+      dst_handle = svga->state.hw_draw.const0_handle;
+   }
+   else {
+      /* we must unmap the buffer before getting the winsys handle */
+      u_upload_unmap(svga->const0_upload);
+
+      dst_handle = svga_buffer_handle(svga, dst_buffer,
+                                      PIPE_BIND_CONSTANT_BUFFER);
+      if (!dst_handle) {
+         pipe_resource_reference(&dst_buffer, NULL);
+         return PIPE_ERROR_OUT_OF_MEMORY;
+      }
+
+      /* save the buffer / handle for next time */
+      pipe_resource_reference(&svga->state.hw_draw.const0_buffer, dst_buffer);
+      svga->state.hw_draw.const0_handle = dst_handle;
    }
 
+   /* Issue the SetSingleConstantBuffer command */
    assert(new_buf_size % 16 == 0);
    ret = SVGA3D_vgpu10_SetSingleConstantBuffer(svga->swc,
                                                0, /* index */
@@ -663,12 +624,14 @@ emit_constbuf_vgpu10(struct svga_context *svga, unsigned shader)
 
    pipe_resource_reference(&dst_buffer, NULL);
 
+   svga->hud.num_const_buf_updates++;
+
    return ret;
 }
 
 
 static enum pipe_error
-emit_consts_vgpu10(struct svga_context *svga, unsigned shader)
+emit_consts_vgpu10(struct svga_context *svga, enum pipe_shader_type shader)
 {
    enum pipe_error ret;
    unsigned dirty_constbufs;
@@ -694,7 +657,8 @@ emit_consts_vgpu10(struct svga_context *svga, unsigned shader)
       struct svga_winsys_surface *handle;
 
       if (buffer) {
-         handle = svga_buffer_handle(svga, &buffer->b.b);
+         handle = svga_buffer_handle(svga, &buffer->b.b,
+                                     PIPE_BIND_CONSTANT_BUFFER);
          enabled_constbufs |= 1 << index;
       }
       else {
@@ -731,6 +695,8 @@ emit_consts_vgpu10(struct svga_context *svga, unsigned shader)
                                                   size);
       if (ret != PIPE_OK)
          return ret;
+
+      svga->hud.num_const_buf_updates++;
    }
 
    svga->state.hw_draw.enabled_constbufs[shader] = enabled_constbufs;
@@ -747,7 +713,7 @@ emit_fs_consts(struct svga_context *svga, unsigned dirty)
 
    /* SVGA_NEW_FS_VARIANT
     */
-   if (variant == NULL)
+   if (!variant)
       return PIPE_OK;
 
    /* SVGA_NEW_FS_CONST_BUFFER
@@ -768,7 +734,7 @@ struct svga_tracked_state svga_hw_fs_constants =
    "hw fs params",
    (SVGA_NEW_FS_CONST_BUFFER |
     SVGA_NEW_FS_VARIANT |
-    SVGA_NEW_TEXTURE_BINDING),
+    SVGA_NEW_TEXTURE_CONSTS),
    emit_fs_consts
 };
 
@@ -782,7 +748,7 @@ emit_vs_consts(struct svga_context *svga, unsigned dirty)
 
    /* SVGA_NEW_VS_VARIANT
     */
-   if (variant == NULL)
+   if (!variant)
       return PIPE_OK;
 
    /* SVGA_NEW_VS_CONST_BUFFER
@@ -803,7 +769,8 @@ struct svga_tracked_state svga_hw_vs_constants =
    "hw vs params",
    (SVGA_NEW_PRESCALE |
     SVGA_NEW_VS_CONST_BUFFER |
-    SVGA_NEW_VS_VARIANT),
+    SVGA_NEW_VS_VARIANT |
+    SVGA_NEW_TEXTURE_CONSTS),
    emit_vs_consts
 };
 
@@ -816,7 +783,7 @@ emit_gs_consts(struct svga_context *svga, unsigned dirty)
 
    /* SVGA_NEW_GS_VARIANT
     */
-   if (variant == NULL)
+   if (!variant)
       return PIPE_OK;
 
    /* SVGA_NEW_GS_CONST_BUFFER
@@ -840,8 +807,10 @@ emit_gs_consts(struct svga_context *svga, unsigned dirty)
 struct svga_tracked_state svga_hw_gs_constants =
 {
    "hw gs params",
-   (SVGA_NEW_GS_CONST_BUFFER |
+   (SVGA_NEW_PRESCALE |
+    SVGA_NEW_GS_CONST_BUFFER |
     SVGA_NEW_RAST |
-    SVGA_NEW_GS_VARIANT),
+    SVGA_NEW_GS_VARIANT |
+    SVGA_NEW_TEXTURE_CONSTS),
    emit_gs_consts
 };