freedreno/a6xx: fix hang with large render target
[mesa.git] / src / gallium / drivers / svga / svga_cmd_vgpu10.c
index 5c121089f918ecf6784372ea0c18a0b832045119..30e174a754affe14ad7b51e1d8271de670ee7695 100644 (file)
@@ -222,6 +222,7 @@ SVGA3D_vgpu10_SetViewports(struct svga_winsys_context *swc,
 {
    SVGA3D_CREATE_CMD_COUNT(SetViewports, SET_VIEWPORTS, SVGA3dViewport);
 
+   cmd->pad0 = 0;
    memcpy(cmd + 1, viewports, count * sizeof(SVGA3dViewport));
 
    swc->commit(swc);
@@ -508,6 +509,7 @@ SVGA3D_vgpu10_SetScissorRects(struct svga_winsys_context *swc,
    if (!cmd)
       return PIPE_ERROR_OUT_OF_MEMORY;
 
+   cmd->pad0 = 0;
    memcpy(cmd + 1, rects, count * sizeof(SVGASignedRect));
 
    swc->commit(swc);
@@ -535,8 +537,9 @@ SVGA3D_vgpu10_Draw(struct svga_winsys_context *swc,
 
    SVGA3D_COPY_BASIC_2(vertexCount, startVertexLocation);
 
-   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    swc->commit(swc);
+   swc->num_draw_commands++;
    return PIPE_OK;
 }
 
@@ -551,8 +554,9 @@ SVGA3D_vgpu10_DrawIndexed(struct svga_winsys_context *swc,
    SVGA3D_COPY_BASIC_3(indexCount, startIndexLocation,
                        baseVertexLocation);
 
-   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    swc->commit(swc);
+   swc->num_draw_commands++;
    return PIPE_OK;
 }
 
@@ -568,8 +572,9 @@ SVGA3D_vgpu10_DrawInstanced(struct svga_winsys_context *swc,
    SVGA3D_COPY_BASIC_4(vertexCountPerInstance, instanceCount,
                        startVertexLocation, startInstanceLocation);
 
-   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    swc->commit(swc);
+   swc->num_draw_commands++;
    return PIPE_OK;
 }
 
@@ -588,8 +593,9 @@ SVGA3D_vgpu10_DrawIndexedInstanced(struct svga_winsys_context *swc,
                        startInstanceLocation);
 
 
-   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    swc->commit(swc);
+   swc->num_draw_commands++;
    return PIPE_OK;
 }
 
@@ -598,8 +604,10 @@ SVGA3D_vgpu10_DrawAuto(struct svga_winsys_context *swc)
 {
    SVGA3D_CREATE_COMMAND(DrawAuto, DRAW_AUTO);
 
-   swc->hints |= SVGA_HINT_FLAG_DRAW_EMITTED;
+   cmd->pad0 = 0;
+   swc->hints |= SVGA_HINT_FLAG_CAN_PRE_FLUSH;
    swc->commit(swc);
+   swc->num_draw_commands++;
    return PIPE_OK;
 }
 
@@ -814,6 +822,9 @@ SVGA3D_vgpu10_DefineDepthStencilView(struct svga_winsys_context *swc,
    cmd->mipSlice = desc->tex.mipSlice;
    cmd->firstArraySlice = desc->tex.firstArraySlice;
    cmd->arraySize = desc->tex.arraySize;
+   cmd->flags = 0;
+   cmd->pad0 = 0;
+   cmd->pad1 = 0;
 
    surface_to_resourceid(swc, surface,
                          &cmd->sid,
@@ -1026,6 +1037,8 @@ SVGA3D_vgpu10_DefineSamplerState(struct svga_winsys_context *swc,
    SVGA3D_COPY_BASIC_5(maxAnisotropy, comparisonFunc,
                        borderColor, minLOD,
                        maxLOD);
+   cmd->pad0 = 0;
+   cmd->pad1 = 0;
 
    swc->commit(swc);
    return PIPE_OK;
@@ -1112,13 +1125,14 @@ SVGA3D_vgpu10_DefineStreamOutput(struct svga_winsys_context *swc,
    cmd->soid = soid;
    cmd->numOutputStreamEntries = numOutputStreamEntries;
 
-   for (i = 0; i < Elements(cmd->streamOutputStrideInBytes); i++)
+   for (i = 0; i < ARRAY_SIZE(cmd->streamOutputStrideInBytes); i++)
       cmd->streamOutputStrideInBytes[i] = streamOutputStrideInBytes[i];
 
    memcpy(cmd->decl, decl,
           sizeof(SVGA3dStreamOutputDeclarationEntry)
-          * SVGA3D_MAX_STREAMOUT_DECLS);
+          * SVGA3D_MAX_DX10_STREAMOUT_DECLS);
 
+   cmd->rasterizedStream = 0;
    swc->commit(swc);
    return PIPE_OK;
 }
@@ -1250,6 +1264,31 @@ SVGA3D_vgpu10_SetSingleConstantBuffer(struct svga_winsys_context *swc,
 }
 
 
+enum pipe_error
+SVGA3D_vgpu10_SetConstantBufferOffset(struct svga_winsys_context *swc,
+                                      unsigned command,
+                                      unsigned slot,
+                                      uint32 offsetInBytes)
+{
+   SVGA3dCmdDXSetConstantBufferOffset *cmd;
+
+   assert(offsetInBytes % 256 == 0);
+
+   cmd = SVGA3D_FIFOReserve(swc, command,
+                            sizeof(SVGA3dCmdDXSetConstantBufferOffset),
+                            0);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->slot = slot;
+   cmd->offsetInBytes = offsetInBytes;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
 enum pipe_error
 SVGA3D_vgpu10_ReadbackSubResource(struct svga_winsys_context *swc,
                                   struct svga_winsys_surface *surface,
@@ -1290,6 +1329,287 @@ SVGA3D_vgpu10_UpdateSubResource(struct svga_winsys_context *swc,
    cmd->subResource = subResource;
    cmd->box = *box;
 
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_GenMips(struct svga_winsys_context *swc,
+                      SVGA3dShaderResourceViewId shaderResourceViewId,
+                      struct svga_winsys_surface *view)
+{
+   SVGA3dCmdDXGenMips *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_GENMIPS,
+                            sizeof(SVGA3dCmdDXGenMips), 1);
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->shaderResourceViewId, NULL, view,
+                           SVGA_RELOC_WRITE);
+   cmd->shaderResourceViewId = shaderResourceViewId;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_vgpu10_BufferCopy(struct svga_winsys_context *swc,
+                          struct svga_winsys_surface *src,
+                          struct svga_winsys_surface *dst,
+                          unsigned srcx, unsigned dstx, unsigned width)
+{
+   SVGA3dCmdDXBufferCopy *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_BUFFER_COPY, sizeof *cmd, 2);
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->dest, NULL, dst, SVGA_RELOC_WRITE);
+   swc->surface_relocation(swc, &cmd->src, NULL, src, SVGA_RELOC_READ);
+   cmd->destX = dstx;
+   cmd->srcX = srcx;
+   cmd->width = width;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_TransferFromBuffer(struct svga_winsys_context *swc,
+                                 struct svga_winsys_surface *src,
+                                 unsigned srcOffset, unsigned srcPitch,
+                                 unsigned srcSlicePitch,
+                                 struct svga_winsys_surface *dst,
+                                 unsigned dstSubResource,
+                                 SVGA3dBox *dstBox)
+{
+   SVGA3dCmdDXTransferFromBuffer *cmd;
+   cmd = SVGA3D_FIFOReserve(swc, SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER,
+                            sizeof(SVGA3dCmdDXTransferFromBuffer), 2);
+
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->srcSid, NULL, src, SVGA_RELOC_READ);
+   swc->surface_relocation(swc, &cmd->destSid, NULL, dst, SVGA_RELOC_WRITE);
+   cmd->srcOffset = srcOffset;
+   cmd->srcPitch = srcPitch;
+   cmd->srcSlicePitch = srcSlicePitch;
+   cmd->destSubResource = dstSubResource;
+   cmd->destBox = *dstBox;
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_IntraSurfaceCopy(struct svga_winsys_context *swc,
+                               struct svga_winsys_surface *surface,
+                               unsigned level, unsigned face,
+                               const SVGA3dCopyBox *box)
+{
+   SVGA3dCmdIntraSurfaceCopy *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_INTRA_SURFACE_COPY,
+                         sizeof(SVGA3dCmdIntraSurfaceCopy),
+                         1);  /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->surface.sid, NULL, surface, SVGA_RELOC_READ | SVGA_RELOC_WRITE);
+   cmd->surface.face = face;
+   cmd->surface.mipmap = level;
+   cmd->box = *box;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+enum pipe_error
+SVGA3D_vgpu10_ResolveCopy(struct svga_winsys_context *swc,
+                          unsigned dstSubResource,
+                          struct svga_winsys_surface *dst,
+                          unsigned srcSubResource,
+                          struct svga_winsys_surface *src,
+                          const SVGA3dSurfaceFormat copyFormat)
+{
+   SVGA3dCmdDXResolveCopy *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_DX_RESOLVE_COPY,
+                         sizeof(SVGA3dCmdDXResolveCopy),
+                         2); /* two relocations */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->dstSubResource = dstSubResource;
+   swc->surface_relocation(swc, &cmd->dstSid, NULL, dst, SVGA_RELOC_WRITE);
+   cmd->srcSubResource = srcSubResource;
+   swc->surface_relocation(swc, &cmd->srcSid, NULL, src, SVGA_RELOC_READ);
+   cmd->copyFormat = copyFormat;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_sm5_DrawIndexedInstancedIndirect(struct svga_winsys_context *swc,
+                                        struct svga_winsys_surface *argBuffer,
+                                        unsigned argOffset)
+{
+   SVGA3dCmdDXDrawIndexedInstancedIndirect *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT,
+                         sizeof(SVGA3dCmdDXDrawIndexedInstancedIndirect),
+                         1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->argsBufferSid, NULL, argBuffer,
+                           SVGA_RELOC_READ);
+   cmd->byteOffsetForArgs = argOffset;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_sm5_DrawInstancedIndirect(struct svga_winsys_context *swc,
+                                 struct svga_winsys_surface *argBuffer,
+                                 unsigned argOffset)
+{
+   SVGA3dCmdDXDrawInstancedIndirect *cmd =
+      SVGA3D_FIFOReserve(swc,
+                         SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT,
+                         sizeof(SVGA3dCmdDXDrawInstancedIndirect),
+                         1); /* one relocation */
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->argsBufferSid, NULL, argBuffer,
+                           SVGA_RELOC_READ);
+   cmd->byteOffsetForArgs = argOffset;
+
+   swc->commit(swc);
+
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_sm5_Dispatch(struct svga_winsys_context *swc,
+                    const uint32 threadGroupCount[3])
+{
+   SVGA3dCmdDXDispatch *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_DISPATCH,
+                            sizeof(SVGA3dCmdDXDispatch),
+                            0);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   cmd->threadGroupCountX = threadGroupCount[0];
+   cmd->threadGroupCountY = threadGroupCount[1];
+   cmd->threadGroupCountZ = threadGroupCount[2];
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+enum pipe_error
+SVGA3D_sm5_DispatchIndirect(struct svga_winsys_context *swc,
+                            struct svga_winsys_surface *argBuffer,
+                            uint32 argOffset)
+{
+   SVGA3dCmdDXDispatchIndirect *cmd;
+
+   cmd = SVGA3D_FIFOReserve(swc,
+                            SVGA_3D_CMD_DX_DISPATCH_INDIRECT,
+                            sizeof(SVGA3dCmdDXDispatchIndirect),
+                            1);
+   if (!cmd)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   swc->surface_relocation(swc, &cmd->argsBufferSid, NULL, argBuffer,
+                           SVGA_RELOC_READ);
+   cmd->byteOffsetForArgs = argOffset;
+
+   swc->commit(swc);
+   return PIPE_OK;
+}
+
+
+/**
+  * We don't want any flush between DefineStreamOutputWithMob and
+  * BindStreamOutput because it will cause partial state in command
+  * buffer. This function make that sure there is enough room for
+  * both commands before issuing them
+  */
+
+enum pipe_error
+SVGA3D_sm5_DefineAndBindStreamOutput(struct svga_winsys_context *swc,
+       SVGA3dStreamOutputId soid,
+       uint32 numOutputStreamEntries,
+       uint32 numOutputStreamStrides,
+       uint32 streamOutputStrideInBytes[SVGA3D_DX_MAX_SOTARGETS],
+       struct svga_winsys_buffer *declBuf,
+       uint32 rasterizedStream,
+       uint32 sizeInBytes)
+{
+   unsigned i;
+   SVGA3dCmdHeader *header;
+   SVGA3dCmdDXDefineStreamOutputWithMob *dcmd;
+   SVGA3dCmdDXBindStreamOutput *bcmd;
+
+   unsigned totalSize = 2 * sizeof(*header) +
+                        sizeof(*dcmd) + sizeof(*bcmd);
+
+   /* Make sure there is room for both commands */
+   header = swc->reserve(swc, totalSize, 2);
+   if (!header)
+      return PIPE_ERROR_OUT_OF_MEMORY;
+
+   /* DXDefineStreamOutputWithMob command */
+   header->id = SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB;
+   header->size = sizeof(*dcmd);
+   dcmd = (SVGA3dCmdDXDefineStreamOutputWithMob *)(header + 1);
+   dcmd->soid= soid;
+   dcmd->numOutputStreamEntries = numOutputStreamEntries;
+   dcmd->numOutputStreamStrides = numOutputStreamStrides;
+   dcmd->rasterizedStream = rasterizedStream;
+
+   for (i = 0; i < ARRAY_SIZE(dcmd->streamOutputStrideInBytes); i++)
+      dcmd->streamOutputStrideInBytes[i] = streamOutputStrideInBytes[i];
+
+
+   /* DXBindStreamOutput command */
+   header = (SVGA3dCmdHeader *)(dcmd + 1);
+
+   header->id = SVGA_3D_CMD_DX_BIND_STREAMOUTPUT;
+   header->size = sizeof(*bcmd);
+   bcmd = (SVGA3dCmdDXBindStreamOutput *)(header + 1);
+
+   bcmd->soid = soid;
+   bcmd->offsetInBytes = 0;
+   swc->mob_relocation(swc, &bcmd->mobid,
+                       &bcmd->offsetInBytes, declBuf, 0,
+                       SVGA_RELOC_WRITE);
+
+   bcmd->sizeInBytes = sizeInBytes;
+   bcmd->offsetInBytes = 0;
+
+
    swc->commit(swc);
    return PIPE_OK;
 }