Gallium: Add format PIPE_FORMAT_R8_SRGB
[mesa.git] / src / gallium / drivers / svga / svga_cmd.c
index 542bd129a89a35b3eb478d244e62f6a818850a0e..5557d208171de11f70c4ba507a4da0ebb0222612 100644 (file)
@@ -45,6 +45,9 @@
  *      Can handle null surface. Does a surface_reallocation so you need
  *      to have allocated the fifo space before converting.
  *
+ *
+ * param flags  mask of SVGA_RELOC_READ / _WRITE
+ *
  * Results:
  *      id is filled out.
  *
@@ -54,7 +57,7 @@
  *----------------------------------------------------------------------
  */
 
-static INLINE void
+static inline void
 surface_to_surfaceid(struct svga_winsys_context *swc, // IN
                      struct pipe_surface *surface,    // IN
                      SVGA3dSurfaceImageId *id,        // OUT
@@ -62,12 +65,12 @@ surface_to_surfaceid(struct svga_winsys_context *swc, // IN
 {
    if (surface) {
       struct svga_surface *s = svga_surface(surface);
-      swc->surface_relocation(swc, &id->sid, s->handle, flags);
-      id->face = s->real_face; /* faces have the same order */
+      swc->surface_relocation(swc, &id->sid, NULL, s->handle, flags);
+      id->face = s->real_layer; /* faces have the same order */
       id->mipmap = s->real_level;
    }
    else {
-      swc->surface_relocation(swc, &id->sid, NULL, flags);
+      swc->surface_relocation(swc, &id->sid, NULL, NULL, flags);
       id->face = 0;
       id->mipmap = 0;
    }
@@ -116,6 +119,10 @@ SVGA3D_FIFOReserve(struct svga_winsys_context *swc,
    header->id = cmd;
    header->size = cmdSize;
 
+   swc->last_command = cmd;
+
+   swc->num_commands++;
+
    return &header[1];
 }
 
@@ -266,7 +273,7 @@ SVGA3D_DestroyContext(struct svga_winsys_context *swc)  // IN
 enum pipe_error
 SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
                           struct svga_winsys_surface *sid, // IN
-                          SVGA3dSurfaceFlags flags,    // IN
+                          SVGA3dSurface1Flags flags,    // IN
                           SVGA3dSurfaceFormat format,  // IN
                           SVGA3dSurfaceFace **faces,   // OUT
                           SVGA3dSize **mipSizes,       // OUT
@@ -280,7 +287,8 @@ SVGA3D_BeginDefineSurface(struct svga_winsys_context *swc,
    if (!cmd)
       return PIPE_ERROR_OUT_OF_MEMORY;
 
-   swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_WRITE);
+   swc->surface_relocation(swc, &cmd->sid, NULL, sid,
+                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
    cmd->surfaceFlags = flags;
    cmd->format = format;
 
@@ -333,7 +341,7 @@ SVGA3D_DefineSurface2D(struct svga_winsys_context *swc,    // IN
    mipSizes[0].height = height;
    mipSizes[0].depth = 1;
 
-   swc->commit(swc);;
+   swc->commit(swc);
 
    return PIPE_OK;
 }
@@ -365,9 +373,10 @@ SVGA3D_DestroySurface(struct svga_winsys_context *swc,
                             SVGA_3D_CMD_SURFACE_DESTROY, sizeof *cmd, 1);
    if (!cmd)
       return PIPE_ERROR_OUT_OF_MEMORY;
-
-   swc->surface_relocation(swc, &cmd->sid, sid, SVGA_RELOC_READ);
-   swc->commit(swc);;
+   
+   swc->surface_relocation(swc, &cmd->sid, NULL, sid,
+                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+   swc->commit(swc);
 
    return PIPE_OK;
 }
@@ -453,8 +462,9 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
    swc->region_relocation(swc, &cmd->guest.ptr, st->hwbuf, 0, region_flags);
    cmd->guest.pitch = st->base.stride;
 
-   swc->surface_relocation(swc, &cmd->host.sid, texture->handle, surface_flags);
-   cmd->host.face = st->face; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
+   swc->surface_relocation(swc, &cmd->host.sid, NULL,
+                           texture->handle, surface_flags);
+   cmd->host.face = st->slice; /* PIPE_TEX_FACE_* and SVGA3D_CUBEFACE_* match */
    cmd->host.mipmap = st->base.level;
 
    cmd->transfer = transfer;
@@ -467,6 +477,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc,
    pSuffix->flags = flags;
 
    swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
 
    return PIPE_OK;
 }
@@ -487,6 +498,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
    SVGA3dCmdSurfaceDMASuffix *pSuffix;
    unsigned region_flags;
    unsigned surface_flags;
+   
+   assert(!swc->have_gb_objects);
 
    if (transfer == SVGA3D_WRITE_HOST_VRAM) {
       region_flags = SVGA_RELOC_READ;
@@ -511,7 +524,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
    swc->region_relocation(swc, &cmd->guest.ptr, guest, 0, region_flags);
    cmd->guest.pitch = 0;
 
-   swc->surface_relocation(swc, &cmd->host.sid, host, surface_flags);
+   swc->surface_relocation(swc, &cmd->host.sid,
+                           NULL, host, surface_flags);
    cmd->host.face = 0;
    cmd->host.mipmap = 0;
 
@@ -534,6 +548,7 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
    pSuffix->flags = flags;
 
    swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
 
    return PIPE_OK;
 }
@@ -833,6 +848,8 @@ SVGA3D_SetShader(struct svga_winsys_context *swc,
 {
    SVGA3dCmdSetShader *cmd;
 
+   assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);
+
    cmd = SVGA3D_FIFOReserve(swc,
                             SVGA_3D_CMD_SET_SHADER, sizeof *cmd,
                             0);
@@ -1005,6 +1022,10 @@ SVGA3D_BeginDrawPrimitives(struct svga_winsys_context *swc,
    *decls = declArray;
    *ranges = rangeArray;
 
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   swc->num_draw_commands++;
+
    return PIPE_OK;
 }
 
@@ -1347,6 +1368,44 @@ SVGA3D_BeginSetRenderState(struct svga_winsys_context *swc,
 }
 
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_BeginGBQuery--
+ *
+ *      GB resource version of SVGA3D_BeginQuery.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static enum pipe_error
+SVGA3D_BeginGBQuery(struct svga_winsys_context *swc,
+                   SVGA3dQueryType type) // IN
+{
+   SVGA3dCmdBeginGBQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_BEGIN_GB_QUERY,
+                            sizeof *cmd,
+                            1);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1369,6 +1428,9 @@ SVGA3D_BeginQuery(struct svga_winsys_context *swc,
 {
    SVGA3dCmdBeginQuery *cmd;
 
+   if (swc->have_gb_objects)
+      return SVGA3D_BeginGBQuery(swc, type);
+
    cmd = SVGA3D_FIFOReserve(swc,
                             SVGA_3D_CMD_BEGIN_QUERY,
                             sizeof *cmd,
@@ -1385,6 +1447,48 @@ SVGA3D_BeginQuery(struct svga_winsys_context *swc,
 }
 
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_EndGBQuery--
+ *
+ *      GB resource version of SVGA3D_EndQuery.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static enum pipe_error
+SVGA3D_EndGBQuery(struct svga_winsys_context *swc,
+                 SVGA3dQueryType type,              // IN
+                 struct svga_winsys_buffer *buffer) // IN/OUT
+{
+   SVGA3dCmdEndGBQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_END_GB_QUERY,
+                            sizeof *cmd,
+                            2);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+
+   swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
+                      0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+
+   swc->commit(swc);
+   
+   return PIPE_OK;
+}
+
+
 /*
  *----------------------------------------------------------------------
  *
@@ -1408,6 +1512,9 @@ SVGA3D_EndQuery(struct svga_winsys_context *swc,
 {
    SVGA3dCmdEndQuery *cmd;
 
+   if (swc->have_gb_objects)
+      return SVGA3D_EndGBQuery(swc, type, buffer);
+
    cmd = SVGA3D_FIFOReserve(swc,
                             SVGA_3D_CMD_END_QUERY,
                             sizeof *cmd,
@@ -1419,7 +1526,49 @@ SVGA3D_EndQuery(struct svga_winsys_context *swc,
    cmd->type = type;
 
    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
-                          SVGA_RELOC_WRITE);
+                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SVGA3D_WaitForGBQuery--
+ *
+ *      GB resource version of SVGA3D_WaitForQuery.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Commits space in the FIFO memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static enum pipe_error
+SVGA3D_WaitForGBQuery(struct svga_winsys_context *swc,
+                     SVGA3dQueryType type,              // IN
+                     struct svga_winsys_buffer *buffer) // IN/OUT
+{
+   SVGA3dCmdWaitForGBQuery *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_WAIT_FOR_GB_QUERY,
+                            sizeof *cmd,
+                            2);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->type = type;
+
+   swc->mob_relocation(swc, &cmd->mobid, &cmd->offset, buffer,
+                      0, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
 
    swc->commit(swc);
 
@@ -1455,6 +1604,9 @@ SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
 {
    SVGA3dCmdWaitForQuery *cmd;
 
+   if (swc->have_gb_objects)
+      return SVGA3D_WaitForGBQuery(swc, type, buffer);
+
    cmd = SVGA3D_FIFOReserve(swc,
                             SVGA_3D_CMD_WAIT_FOR_QUERY,
                             sizeof *cmd,
@@ -1466,7 +1618,306 @@ SVGA3D_WaitForQuery(struct svga_winsys_context *swc,
    cmd->type = type;
 
    swc->region_relocation(swc, &cmd->guestResult, buffer, 0,
-                          SVGA_RELOC_WRITE);
+                          SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_BindGBShader(struct svga_winsys_context *swc,
+                    struct svga_winsys_gb_shader *gbshader)
+{
+   SVGA3dCmdBindGBShader *cmd = 
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_BIND_GB_SHADER,
+                         sizeof *cmd,
+                         2);  /* two relocations */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->shader_relocation(swc, &cmd->shid, &cmd->mobid,
+                         &cmd->offsetInBytes, gbshader, 0);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_SetGBShader(struct svga_winsys_context *swc,
+                   SVGA3dShaderType type,  // IN
+                   struct svga_winsys_gb_shader *gbshader)
+{
+   SVGA3dCmdSetShader *cmd;
+
+   assert(type == SVGA3D_SHADERTYPE_VS || type == SVGA3D_SHADERTYPE_PS);
+   
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SET_SHADER,
+                            sizeof *cmd,
+                            2);  /* two relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+   
+   cmd->cid = swc->cid;
+   cmd->type = type;
+   if (gbshader)
+      swc->shader_relocation(swc, &cmd->shid, NULL, NULL, gbshader, 0);
+   else
+      cmd->shid = SVGA_ID_INVALID;
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/**
+ * \param flags  mask of SVGA_RELOC_READ / _WRITE
+ */
+enum pipe_error
+SVGA3D_BindGBSurface(struct svga_winsys_context *swc,
+                     struct svga_winsys_surface *surface)
+{
+   SVGA3dCmdBindGBSurface *cmd = 
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_BIND_GB_SURFACE,
+                         sizeof *cmd,
+                         2);  /* two relocations */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, &cmd->mobid, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Update an image in a guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+enum pipe_error
+SVGA3D_UpdateGBImage(struct svga_winsys_context *swc,
+                     struct svga_winsys_surface *surface,
+                     const SVGA3dBox *box,
+                     unsigned face, unsigned mipLevel)
+
+{
+   SVGA3dCmdUpdateGBImage *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_UPDATE_GB_IMAGE,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+   cmd->image.face = face;
+   cmd->image.mipmap = mipLevel;
+   cmd->box = *box;
+
+   swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Update an entire guest-backed surface.
+ * (Inform the device that the guest-contents have been updated.)
+ */
+enum pipe_error
+SVGA3D_UpdateGBSurface(struct svga_winsys_context *swc,
+                       struct svga_winsys_surface *surface)
+{
+   SVGA3dCmdUpdateGBSurface *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_UPDATE_GB_SURFACE,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_WRITE | SVGA_RELOC_INTERNAL);
+
+   swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Readback an image in a guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+enum pipe_error
+SVGA3D_ReadbackGBImage(struct svga_winsys_context *swc,
+                       struct svga_winsys_surface *surface,
+                       unsigned face, unsigned mipLevel)
+{
+   SVGA3dCmdReadbackGBImage *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_READBACK_GB_IMAGE,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+   cmd->image.face = face;
+   cmd->image.mipmap = mipLevel;
+
+   swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   return PIPE_OK;
+}
+
+
+/**
+ * Readback an entire guest-backed surface.
+ * (Request the device to flush the dirty contents into the guest.)
+ */
+enum pipe_error
+SVGA3D_ReadbackGBSurface(struct svga_winsys_context *swc,
+                         struct svga_winsys_surface *surface)
+{
+   SVGA3dCmdReadbackGBSurface *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_READBACK_GB_SURFACE,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+
+   swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_ReadbackGBImagePartial(struct svga_winsys_context *swc,
+                              struct svga_winsys_surface *surface,
+                              unsigned face, unsigned mipLevel,
+                              const SVGA3dBox *box,
+                              bool invertBox)
+{
+   SVGA3dCmdReadbackGBImagePartial *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+   cmd->image.face = face;
+   cmd->image.mipmap = mipLevel;
+   cmd->box = *box;
+   cmd->invertBox = invertBox;
+
+   swc->commit(swc);
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_InvalidateGBImagePartial(struct svga_winsys_context *swc,
+                                struct svga_winsys_surface *surface,
+                                unsigned face, unsigned mipLevel,
+                                const SVGA3dBox *box,
+                                bool invertBox)
+{
+   SVGA3dCmdInvalidateGBImagePartial *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->image.sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+   cmd->image.face = face;
+   cmd->image.mipmap = mipLevel;
+   cmd->box = *box;
+   cmd->invertBox = invertBox;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_InvalidateGBSurface(struct svga_winsys_context *swc,
+                           struct svga_winsys_surface *surface)
+{
+   SVGA3dCmdInvalidateGBSurface *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_INVALIDATE_GB_SURFACE,
+                         sizeof *cmd,
+                         1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->sid, NULL, surface,
+                           SVGA_RELOC_READ | SVGA_RELOC_INTERNAL);
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_SetGBShaderConstsInline(struct svga_winsys_context *swc,
+                              unsigned regStart,
+                              unsigned numRegs,
+                              SVGA3dShaderType shaderType,
+                              SVGA3dShaderConstType constType,
+                              const void *values)
+{
+   SVGA3dCmdSetGBShaderConstInline *cmd;
+
+   assert(numRegs > 0);
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE,
+                            sizeof *cmd + numRegs * sizeof(float[4]),
+                            0); /* no relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->cid = swc->cid;
+   cmd->regStart = regStart;
+   cmd->shaderType = shaderType;
+   cmd->constType = constType;
+
+   memcpy(&cmd[1], values, numRegs * sizeof(float[4]));
 
    swc->commit(swc);