Add a flag for persistent mapping

And a function to "flush" a mapped buffer
This commit is contained in:
Chris Robinson
2018-01-23 10:38:27 -08:00
parent ad61392318
commit 4f9a0460c4
3 changed files with 49 additions and 8 deletions
+3
View File
@@ -53,11 +53,14 @@ typedef unsigned int ALbitfieldSOFT;
#define AL_MAP_READ_BIT_SOFT 0x01000000
#define AL_MAP_WRITE_BIT_SOFT 0x02000000
#define AL_PRESERVE_DATA_BIT_SOFT 0x04000000
#define AL_MAP_PERSISTENT_BIT_SOFT 0x08000000
typedef void* (AL_APIENTRY*LPALMAPBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length, ALbitfieldSOFT access);
typedef void (AL_APIENTRY*LPALUNMAPBUFFERSOFT)(ALuint buffer);
typedef void (AL_APIENTRY*LPALFLUSHMAPPEDBUFFERSOFT)(ALuint buffer, ALsizei offset, ALsizei length);
#ifdef AL_ALEXT_PROTOTYPES
AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length, ALbitfieldSOFT access);
AL_API void AL_APIENTRY alUnmapBufferSOFT(ALuint buffer);
AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length);
#endif
#endif
+43 -6
View File
@@ -51,9 +51,9 @@ static ALsizei SanitizeAlignment(enum UserFmtType type, ALsizei align);
#define FORMAT_MASK 0x00ffffff
#define CONSTRUCT_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT)
#define CONSTRUCT_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_PRESERVE_DATA_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
#define INVALID_FORMAT_MASK ~(FORMAT_MASK | CONSTRUCT_FLAGS)
#define MAP_ACCESS_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT)
#define MAP_ACCESS_FLAGS (AL_MAP_READ_BIT_SOFT | AL_MAP_WRITE_BIT_SOFT | AL_MAP_PERSISTENT_BIT_SOFT)
AL_API ALvoid AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
@@ -232,18 +232,18 @@ AL_API void* AL_APIENTRY alMapBufferSOFT(ALuint buffer, ALsizei offset, ALsizei
WriteLock(&albuf->lock);
if(((access&AL_MAP_READ_BIT_SOFT) && !(albuf->Access&AL_MAP_READ_BIT_SOFT)) ||
((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)))
((access&AL_MAP_WRITE_BIT_SOFT) && !(albuf->Access&AL_MAP_WRITE_BIT_SOFT)) ||
((access&AL_MAP_PERSISTENT_BIT_SOFT) && !(albuf->Access&AL_MAP_PERSISTENT_BIT_SOFT)))
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done);
if(offset < 0 || offset >= albuf->OriginalSize ||
length <= 0 || length > albuf->OriginalSize - offset)
SET_ERROR_AND_GOTO(context, AL_INVALID_VALUE, unlock_done);
if(ReadRef(&albuf->ref) != 0 || albuf->MappedAccess != 0)
if(albuf->MappedAccess != 0 ||
(!(access&AL_MAP_PERSISTENT_BIT_SOFT) && ReadRef(&albuf->ref) != 0))
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, unlock_done);
retval = (ALbyte*)albuf->data + offset;
albuf->MappedAccess = access;
if((access&AL_MAP_WRITE_BIT_SOFT) && !(access&AL_MAP_READ_BIT_SOFT))
memset(retval, 0x55, length);
unlock_done:
WriteUnlock(&albuf->lock);
@@ -281,6 +281,43 @@ done:
ALCcontext_DecRef(context);
}
AL_API void AL_APIENTRY alFlushMappedBufferSOFT(ALuint buffer, ALsizei offset, ALsizei length)
{
ALCdevice *device;
ALCcontext *context;
ALbuffer *albuf;
context = GetContextRef();
if(!context) return;
device = context->Device;
LockBuffersRead(device);
if((albuf=LookupBuffer(device, buffer)) == NULL)
SET_ERROR_AND_GOTO(context, AL_INVALID_NAME, done);
WriteLock(&albuf->lock);
if(albuf->MappedAccess == 0 || !(albuf->MappedAccess&AL_MAP_WRITE_BIT_SOFT))
alSetError(context, AL_INVALID_OPERATION);
/* TODO: Should check mapped range. */
else if(offset < 0 || offset >= albuf->OriginalSize ||
length <= 0 || length > albuf->OriginalSize - offset)
alSetError(context, AL_INVALID_VALUE);
else
{
/* FIXME: Need to use some method of double-buffering for the mixer and
* app to hold separate memory, which can be safely transfered
* asynchronously. Currently we just say the app shouldn't write where
* OpenAL's reading, and hope for the best...
*/
ATOMIC_THREAD_FENCE(almemory_order_seq_cst);
}
WriteUnlock(&albuf->lock);
done:
UnlockBuffersRead(device);
ALCcontext_DecRef(context);
}
AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, const ALvoid *data, ALsizei offset, ALsizei length)
{
enum UserFmtChannels srcchannels = UserFmtMono;
+3 -2
View File
@@ -760,7 +760,8 @@ static ALboolean SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp p
}
WriteLock(&Source->queue_lock);
if(buffer && buffer->MappedAccess != 0)
if(buffer && buffer->MappedAccess != 0 &&
!(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
{
WriteUnlock(&Source->queue_lock);
UnlockBuffersRead(device);
@@ -2888,7 +2889,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint src, ALsizei nb, const ALu
ReadLock(&buffer->lock);
IncrementRef(&buffer->ref);
if(buffer->MappedAccess != 0)
if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
{
WriteUnlock(&source->queue_lock);
SET_ERROR_AND_GOTO(context, AL_INVALID_OPERATION, buffer_error);