r300: Predict emit size for next rendering operation.
We do flush for cmd buffer in case there isn't enough space left for whole rendering operation. This protects dma regions from getting released in middle of state emit. Signed-off-by: Pauli Nieminen <suokkos@gmail.com>
This commit is contained in:
@@ -38,6 +38,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||||||
|
|
||||||
#include "r300_context.h"
|
#include "r300_context.h"
|
||||||
|
|
||||||
|
#define CACHE_FLUSH_BUFSZ (4*2)
|
||||||
|
#define PRE_EMIT_STATE_BUFSZ (2+2)
|
||||||
|
#define AOS_BUFSZ(nr) (3+(nr >>1)*3 + (nr&1)*2 + (nr*2))
|
||||||
|
#define FIREAOS_BUFSZ (3)
|
||||||
|
#define SCISSORS_BUFSZ (3)
|
||||||
|
|
||||||
extern void r300InitCmdBuf(r300ContextPtr r300);
|
extern void r300InitCmdBuf(r300ContextPtr r300);
|
||||||
void r300_emit_scissor(GLcontext *ctx);
|
void r300_emit_scissor(GLcontext *ctx);
|
||||||
|
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include "r300_render.h"
|
#include "r300_render.h"
|
||||||
#include "r300_state.h"
|
#include "r300_state.h"
|
||||||
#include "r300_tex.h"
|
#include "r300_tex.h"
|
||||||
|
#include "r300_cmdbuf.h"
|
||||||
|
|
||||||
#include "radeon_buffer_objects.h"
|
#include "radeon_buffer_objects.h"
|
||||||
|
|
||||||
@@ -567,6 +568,34 @@ static void r300FreeData(GLcontext *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, GLuint nr_prims)
|
||||||
|
{
|
||||||
|
struct r300_context *r300 = R300_CONTEXT(ctx);
|
||||||
|
struct r300_vertex_buffer *vbuf = &r300->vbuf;
|
||||||
|
int flushed;
|
||||||
|
GLuint dwords;
|
||||||
|
GLuint state_size;
|
||||||
|
|
||||||
|
dwords = 2*CACHE_FLUSH_BUFSZ;
|
||||||
|
dwords += PRE_EMIT_STATE_BUFSZ;
|
||||||
|
dwords += (AOS_BUFSZ(vbuf->num_attribs)
|
||||||
|
+ SCISSORS_BUFSZ
|
||||||
|
+ FIREAOS_BUFSZ )*nr_prims;
|
||||||
|
|
||||||
|
state_size= radeonCountEmitSize(&r300->radeon);
|
||||||
|
flushed = rcommonEnsureCmdBufSpace(&r300->radeon,
|
||||||
|
dwords + state_size,
|
||||||
|
__FUNCTION__);
|
||||||
|
if (flushed)
|
||||||
|
dwords += radeonCountEmitSize(&r300->radeon);
|
||||||
|
else
|
||||||
|
dwords += state_size;
|
||||||
|
|
||||||
|
if (RADEON_DEBUG & DEBUG_PRIMS)
|
||||||
|
fprintf(stderr, "%s: total prediction size is %d.\n", __FUNCTION__, dwords);
|
||||||
|
return dwords;
|
||||||
|
}
|
||||||
|
|
||||||
static GLboolean r300TryDrawPrims(GLcontext *ctx,
|
static GLboolean r300TryDrawPrims(GLcontext *ctx,
|
||||||
const struct gl_client_array *arrays[],
|
const struct gl_client_array *arrays[],
|
||||||
const struct _mesa_prim *prim,
|
const struct _mesa_prim *prim,
|
||||||
@@ -592,8 +621,6 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
|
|||||||
|
|
||||||
r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx));
|
r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx));
|
||||||
|
|
||||||
/* ensure we have the cmd buf space in advance to cover
|
|
||||||
* the state + DMA AOS pointers */
|
|
||||||
rcommonEnsureCmdBufSpace(&r300->radeon,
|
rcommonEnsureCmdBufSpace(&r300->radeon,
|
||||||
r300->radeon.hw.max_state_size + (60*sizeof(int)),
|
r300->radeon.hw.max_state_size + (60*sizeof(int)),
|
||||||
__FUNCTION__);
|
__FUNCTION__);
|
||||||
@@ -607,6 +634,10 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
|
|||||||
|
|
||||||
r300UpdateShaderStates(r300);
|
r300UpdateShaderStates(r300);
|
||||||
|
|
||||||
|
/* ensure we have the cmd buf space in advance to cover
|
||||||
|
* the state + DMA AOS pointers */
|
||||||
|
r300PredictTryDrawPrimsSize(ctx, nr_prims);
|
||||||
|
|
||||||
r300SetupIndexBuffer(ctx, ib);
|
r300SetupIndexBuffer(ctx, ib);
|
||||||
|
|
||||||
r300AllocDmaRegions(ctx, arrays, max_index + 1);
|
r300AllocDmaRegions(ctx, arrays, max_index + 1);
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "radeon_bocs_wrapper.h"
|
#include "radeon_bocs_wrapper.h"
|
||||||
|
|
||||||
void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
|
int rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
|
||||||
int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
|
int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
|
||||||
int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
|
int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
|
||||||
void rcommonInitCmdBuf(radeonContextPtr rmesa);
|
void rcommonInitCmdBuf(radeonContextPtr rmesa);
|
||||||
|
@@ -1189,14 +1189,16 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
|
|||||||
*
|
*
|
||||||
* \param dwords The number of dwords we need to be free on the command buffer
|
* \param dwords The number of dwords we need to be free on the command buffer
|
||||||
*/
|
*/
|
||||||
void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
|
int rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
|
||||||
{
|
{
|
||||||
if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
|
if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
|
||||||
|| radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
|
|| radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
|
||||||
/* If we try to flush empty buffer there is too big rendering operation. */
|
/* If we try to flush empty buffer there is too big rendering operation. */
|
||||||
assert(rmesa->cmdbuf.cs->cdw);
|
assert(rmesa->cmdbuf.cs->cdw);
|
||||||
rcommonFlushCmdBuf(rmesa, caller);
|
rcommonFlushCmdBuf(rmesa, caller);
|
||||||
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcommonInitCmdBuf(radeonContextPtr rmesa)
|
void rcommonInitCmdBuf(radeonContextPtr rmesa)
|
||||||
|
Reference in New Issue
Block a user