/*---------------------------------------------------------------------------* Copyright (C) 2010-2011 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ #ifndef _CAFE_GX2R_BUFFER_H_ #define _CAFE_GX2R_BUFFER_H_ #ifdef __cplusplus extern "C" { #endif // __cplusplus /// @addtogroup GX2RGroup /// @{ /// \brief \ref GX2RDestroyBuffer but with GX2R_OPTION flags (see \ref GX2RResourceFlags) /// /// \donotcall \gx2_typical \userheap \enddonotcall /// void GX2API GX2RDestroyBufferEx(GX2RBuffer* gx2Buffer, GX2RResourceFlags optionFlags); /// \brief \ref GX2RLockBuffer but with GX2R_OPTION flags (see \ref GX2RResourceFlags) /// /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall /// void* GX2API GX2RLockBufferEx(const GX2RBuffer* gx2Buffer, GX2RResourceFlags optionFlags); /// \brief \ref GX2RLockBufferRegion but with GX2R_OPTION flags (see \ref GX2RResourceFlags) /// ***UNIMPLEMENTED in this release*** /// /// \donotcall \threadsafe \devonly \enddonotcall /// void* GX2API GX2RLockBufferRegionEx(const GX2RBuffer* gx2Buffer, u32 byteOffset, u32 byteCount, GX2RResourceFlags optionFlags); /// \brief \ref GX2RUnlockBuffer but with GX2R_OPTION flags (see \ref GX2RResourceFlags) /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \writesgpu{if the buffer resource usage is any GPU usable type (for example, \ref GX2R_BIND_VERTEX_BUFFER)} /// void GX2API GX2RUnlockBufferEx(const GX2RBuffer* gx2Buffer, GX2RResourceFlags optionFlags); /// \brief Create a buffer object. /// /// \param gx2Buffer Address of a filled-in \ref GX2RBuffer struct. /// \return GX2_TRUE if creation succeeds, GX2_FALSE otherwise /// /// \note This function will allocate the memory via the allocator callback (see \ref GX2RSetAllocator). /// If \ref GX2R_USAGE_GPU_WRITE or \ref GX2R_USAGE_DMA_WRITE is specified, DCInvalidateRange() will be called /// to clear any CPU cache lines which could unexpectedly overwrite the data. /// If the allocator callback writes to the memory, for example, a debug fill value, the cache must be flushed /// with GX2Invalidate(GX2_INVALIDATE_CPU). /// No GPU cache invalidation is performed - this is done in \ref GX2RUnlockBuffer. /// Consider using the GXUT helper functions to create common types. /// /// \donotcall \gx2_typical \userheap \enddonotcall /// GX2Boolean GX2API GX2RCreateBuffer(GX2RBuffer* gx2Buffer); /// \brief Create a buffer object from user supplied memory. /// /// \param gx2Buffer Address of a filled-in \ref GX2RBuffer struct. /// \param pUserMem Pointer to existing memory for the buffer. /// \param userByteCount Size of the user memory block, must be >= the required size for the buffer (see \ref GX2RGetBufferAllocationSize) /// \return GX2_TRUE if creation succeeds, GX2_FALSE otherwise /// /// \note \ref GX2RCreateBuffer should be used in preference to this version except where absolutely necessary. /// Cache invalidation behaviour is the same as \ref GX2RCreateBuffer. /// Although the memory pointer is accessible without using Lock/Unlock, these should still be used as they provide important /// hooks for debugging and profiling. Lock/Unlock will also manage CPU and GPU cache invalidation, although /// this can be suppressed per buffer or per call with the \ref GX2R_OPTION_NO_CPU_INVALIDATE and \ref GX2R_OPTION_NO_GPU_INVALIDATE flags, /// in which case \ref GX2RInvalidateBuffer, \ref GX2RInvalidateMemory or \ref GX2Invalidate should be used. /// \ref GX2RDestroyBuffer must still be called for user memory buffers. /// /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall /// GX2Boolean GX2API GX2RCreateBufferUserMemory(GX2RBuffer* gx2Buffer, void* pUserMem, u32 userByteCount); /// \brief Destroy a GX2R buffer object. /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// /// \note Memory will be freed via the default allocator or user callback. /// If the buffer was created from user memory via \ref GX2RCreateBufferUserMemory this function is /// still necessary to mark the buffer as deleted. /// Destroying a buffer that was never created or has already been destroyed is not an error. /// /// \donotcall \gx2_typical \userheap \enddonotcall /// GX2_INLINE void GX2RDestroyBuffer(GX2RBuffer* gx2Buffer) { GX2RDestroyBufferEx(gx2Buffer, GX2R_OPTION_NONE); } /// \brief Lock a GX2R buffer object and return a pointer to the memory. /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// \return Memory address of the start of the buffer /// /// \note The returned buffer memory may be read or written by the CPU or via DMA transfer (or even the GPU), /// however it is imperative the correct usage flags are set in \ref GX2RResourceFlags to ensure cache coherency. /// \ref GX2RUnlockBuffer must be called before the buffer object is used by any other GX2R APIs. /// /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall /// GX2_INLINE void* GX2RLockBuffer(const GX2RBuffer* gx2Buffer) { return GX2RLockBufferEx(gx2Buffer, GX2R_OPTION_NONE); } /// \brief Lock a subrange of a GX2R buffer object and return a pointer to the memory. /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// \param byteOffset Start offset of the region to lock /// \param byteCount Size of the region to lock /// \return Memory address of the locked buffer region /// /// \note See \ref GX2RLockBuffer for more info. /// ***UNIMPLEMENTED in this release*** /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2_INLINE void* GX2RLockBufferRegion(const GX2RBuffer* gx2Buffer, u32 byteOffset, u32 byteCount) { return GX2RLockBufferRegionEx(gx2Buffer, byteOffset, byteCount, GX2R_OPTION_NONE); } /// \brief Unlock a GX2R buffer object. /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// /// \note This function will perform any necessary CPU and GPU cache invalidation. /// Cache invalidation can be controlled with \ref GX2R_OPTION_NO_CPU_INVALIDATE and GX2R_OPTION_NO_GPU_INVALIDATE, /// either per buffer in the resourceFlags, or per call when passed to \ref GX2RUnlockBufferEx. /// We recommend letting the API handle correct CPU and GPU cache invalidation almost always; however, /// in some cases, it can be more efficient to do manual invalidation, for example, updating a large /// number of objects and invalidating the GPU over the entire range once only. /// See \ref GX2RInvalidateBuffer, \ref GX2RInvalidateMemory and \ref GX2Invalidate. /// The buffer memory pointer must not be used after the buffer is unlocked. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \writesgpu{if the buffer resource usage is any GPU usable type (for example, \ref GX2R_BIND_VERTEX_BUFFER)} /// GX2_INLINE void GX2RUnlockBuffer(const GX2RBuffer* gx2Buffer) { GX2RUnlockBufferEx(gx2Buffer, GX2R_OPTION_NONE); } /// \brief Returns true if the buffer has memory allocated; that is, created but not yet destroyed /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// /// \donotcall \threadsafe \devonly \enddonotcall /// GX2Boolean GX2API GX2RBufferExists(const GX2RBuffer* gx2Buffer); /// \brief Give the buffer a meaningful name for debug and profiling. /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// \param name Name string. Copied into the API. /// /// \note Ignored in release builds. /// Buffer must have memory allocated (that is \ref GX2RBufferExists is true) when this is called. /// /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall /// void GX2API GX2RSetBufferName(GX2RBuffer* gx2Buffer, const char* name); /// \brief Get buffer debug name - see \ref GX2RSetBufferName /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall /// const char* GX2API GX2RGetBufferName(const GX2RBuffer* gx2Buffer); /// \brief Set the attribute buffer /// /// \param vertexBuffer Buffer object created with \ref GX2R_BIND_VERTEX_BUFFER flag. /// \param slot Which shader attribute slot to bind to. /// \param stride Stride in bytes between the start of one vertex and the next /// \param byteOffset Offset in bytes from the start of the buffer to the first vertex /// /// \note The offset parameter can be used when several attribute streams are interleaved into /// a single array-of-vertex buffer, and/or to pack several geometry elements into a single buffer. /// Stride of 0 is valid (TODO: check this) /// Use \ref GX2UTSetAttributeBuffer in the common case that stride==vertexBuffer->elementSize /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetAttributeBuffer(const GX2RBuffer* vertexBuffer, u32 slot, u32 stride, u32 byteOffset); /// \brief Set a Uniform Block buffer for the Vertex Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \param uniformBlock Buffer object created with \ref GX2R_BIND_UNIFORM_BLOCK /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param byteOffset Offset in bytes from the start of the buffer to the first element /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetVertexUniformBlock(const GX2RBuffer* uniformBlock, u32 location, u32 byteOffset); /// \brief Set a Uniform Block buffer for the Geometry Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \param uniformBlock Buffer object created with \ref GX2R_BIND_UNIFORM_BLOCK /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param byteOffset Offset in bytes from the start of the buffer to the first element /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetGeometryUniformBlock(const GX2RBuffer* uniformBlock, u32 location, u32 byteOffset); /// \brief Set a Uniform Block buffer for the Pixel Shader /// /// Use in \ref GX2_SHADER_MODE_UNIFORM_BLOCK or \ref GX2_SHADER_MODE_GEOMETRY_SHADER only. /// /// \param uniformBlock Buffer object created with \ref GX2R_BIND_UNIFORM_BLOCK /// \param location Hardware location of uniform block (\ref GX2UniformBlock) /// \param byteOffset Offset in bytes from the start of the buffer to the first element /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetPixelUniformBlock(const GX2RBuffer* uniformBlock, u32 location, u32 byteOffset); /// \brief Set the stream out buffer to be used as the specified stream out target /// /// \param soTarget The stream out target to setup /// \param streamOutBuffer Pointer to stream out buffer structure to use /// \note The GX2RStreamOutBuffer must be initialized with a GX2RBuffer, and the dataPtr field must be NULL. /// You can call \ref GX2SetStreamOutBuffer() directly as it will detect dataPtr==NULL and use the buffer, however this API /// provides some extra validation. /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetStreamOutBuffer(u32 soTarget, const GX2StreamOutBuffer* streamOutBuffer); /// \brief Draw indexed primitives /// /// \param primitiveType Type of primitive to draw /// \param indexBuffer Buffer of type \ref GX2R_BIND_INDEX_BUFFER holding indices /// \param indexFormat Specifies if indices are 16-bit or 32-bit /// \param indexCount How many vertices to draw /// \param startIndex Which index in the index buffer is considered first /// \param startVertex Which vertex in vertex buffers is considered first /// \param numInstances How many instances to draw /// /// \note startVertex does not apply to attributes indexed by instance ID /// \note See also \ref GX2UTDrawIndexed() to draw with common default parameters /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RDrawIndexed(GX2PrimitiveType primitiveType, const GX2RBuffer* indexBuffer, GX2IndexFormat indexFormat, u32 indexCount, u32 startIndex, u32 startVertex, u32 numInstances); /// \brief Draw indexed primitives copying indices into the command buffer. /// This is the same as \ref GX2RDrawIndexed() except indexBuffer need not continue to exist as indices are copied /// \note See also \ref GX2UTDrawIndexedImmediate() to draw with common default parameters /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RDrawIndexedImmediate(GX2PrimitiveType primitiveType, const GX2RBuffer* indexBuffer, GX2IndexFormat indexFormat, u32 indexCount, u32 startIndex, u32 startVertex, u32 numInstances); /// \brief Begin recording a display list that can be executed later. /// \param displayList Buffer of type \ref GX2R_BIND_DISPLAY_LIST /// \param enableProfiling Initial profiling state for the display list /// \param optionFlags Option to suppress CPU cache invalidation /// \note The profiling state is stored with the state context so if GX2SetContextState is called /// within the display list the profiling state (enabled or disabled) may change. /// If GX2SetContextState() is not called in the display list the correct context state /// (with respect to profiling) must be set before calling GX2RCallDisplayList() or /// GX2RDirectCallDisplayList() to execute the display list. /// Note this API will perform the necessary cache invalidation on the buffer, unless suppressed with optionFlags /// /// \donotcall \gx2_dl \enddonotcall /// void GX2API GX2RBeginDisplayListEx(const GX2RBuffer* displayList, GX2Boolean enableProfiling, GX2RResourceFlags optionFlags); /// \brief Begin recording a display list that can be executed later. /// \param displayList Buffer of type \ref GX2R_BIND_DISPLAY_LIST /// \note HW Profiling will be enabled for the Display list. /// Note this API will perform the necessary cache invalidation on the buffer /// /// \donotcall \gx2_dl \enddonotcall /// GX2_INLINE void GX2RBeginDisplayList(const GX2RBuffer* displayList) { GX2RBeginDisplayListEx(displayList, GX2_ENABLE, GX2R_OPTION_NONE); } /// \brief End the display list generation. /// /// \param displayList Buffer of type \ref GX2R_BIND_DISPLAY_LIST previously set in \ref GX2RBeginDisplayList /// \return the actual size of the display list in bytes. /// Note this API will assert if the display list has overrun the buffer size. /// /// \donotcall \gx2_typical \enddonotcall /// u32 GX2API GX2REndDisplayList(const GX2RBuffer* displayList); /// \brief Execute the displaylist by adding it to the current display list or command buffer. /// /// \param displayList Buffer of type \ref GX2R_BIND_DISPLAY_LIST /// \param byteSize Actual size of the display list, as returned by \ref GX2REndDisplayList() /// \note A display list referenced in this call cannot call another display list (no nesting). /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RCallDisplayList(const GX2RBuffer* displayList, u32 byteSize); /// \brief Execute the displaylist by adding it directly to the graphics ring buffer. /// /// \param displayList Buffer of type \ref GX2R_BIND_DISPLAY_LIST /// \param byteSize Actual size of the display list, as returned by \ref GX2REndDisplayList() /// \note This function can only be called from the main thread. /// /// \donotcall \nomulticore \gx2_dl \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RDirectCallDisplayList(const GX2RBuffer* displayList, u32 byteSize); /// \brief Set a ring buffer for geometry shader input (VS output) /// /// \param ringInBuffer Buffer of type \ref GX2R_BIND_GS_RING /// /// \note This function invokes a full pipeline flush. /// Buffer size must be calculated with GX2CalcGeometryShaderInputRingBufferSize(), /// or else see \ref GX2UTCreateGeometryShaderInputRingBuffer() /// See also \ref GX2UTSetGeometryShaderRingBuffers() /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetGeometryShaderInputRingBuffer(const GX2RBuffer* ringInBuffer); /// \brief Set a ring buffer for geometry shader output (PS input) /// /// \param ringOutBuffer Buffer of type \ref GX2R_BIND_GS_RING /// /// \note This function invokes a full pipeline flush. /// Buffer size must be calculated with \ref GX2CalcGeometryShaderOutputRingBufferSize(), /// or else see \ref GX2UTCreateGeometryShaderOutputRingBuffer() /// See also \ref GX2UTSetGeometryShaderRingBuffers() /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \alwayswritesgpu /// void GX2API GX2RSetGeometryShaderOutputRingBuffer(const GX2RBuffer* ringOutBuffer); /// \brief Create a fetch shader based on the specified attribute stream list. /// /// \param fetchShader User-allocated instance of \ref GX2FetchShader structure /// \param shaderProgram Buffer of type GX2R_BIND_SHADER_PROGRAM for the fetch shader binary code /// \param attribCount Number of attribute streams /// \param attribStreams User-allocated array of \ref GX2AttribStream structures containing information about all attribute streams /// \param type The type of fetch shader to generate /// \param tessMode Tesselation mode, only valid if type is not GX2_FETCH_SHADER_TESSELATION_NONE /// /// \note See also GX2UTInitFetchShader() /// ***UNIMPLEMENTED in this release*** /// /// \donotcall \threadsafe \devonly \enddonotcall /// void GX2API GX2RInitFetchShader(GX2FetchShader* fetchShader, const GX2RBuffer* shaderProgram, u32 attribCount, const GX2AttribStream* attribStreams, GX2FetchShaderType type, GX2TessellationMode tessMode); /// \brief Utility function for custom allocator or user memory buffer to get the correct alignment for the specified buffer type /// \note Useful for custom allocators or user memory APIs. /// Only works with buffers types - for surfaces use GX2CalcSurfaceSizeAndAlignment() /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2RGetBufferAlignment(GX2RResourceFlags resourceFlags); /// \brief Utility function for custom allocator or user memory buffer to get the correct size for the specified buffer /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// /// \note This is not simply elementSize*elementCount as the end of the block may be rounded up to a 64-byte boundary. /// The CPU cache prefetching is in 64-byte granularity, so without this alignment it may read into adjacent memory. /// If that memory is written to by the GPU, then read by the CPU, the first 32 bytes will be incorrect. /// Useful for custom allocators or user memory APIs. /// Note this is a calculation of the required size based on the parameters, not necessarily the actual allocation size /// if a custom allocator or user memory was employed. /// The actual allocation size will also be greater if GX2R_DEBUG_GUARD_BANDS_ENABLED debug option is set - see \ref GX2RGetBufferGuardBandSize. /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2RGetBufferAllocationSize(const GX2RBuffer* gx2Buffer); /// \brief Utility function to perform correct cache invalidation for user memory /// \param resourceFlags Type/semantics/options for the data referenced by pMem /// \param pMem User memory pointer to buffer data /// \param byteCount Size of data at pMem /// /// \note Typically when using the GX2R APIs this will not be necessary, however this function is useful when using user memory /// via \ref GX2RCreateBufferUserMemory and \ref GX2RResourceFlags to suppress invalidation within the API. /// See also \ref GX2RInvalidateBuffer /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \writesgpu{if the buffer resource usage is any GPU usable type (for example, \ref GX2R_BIND_VERTEX_BUFFER)} /// void GX2API GX2RInvalidateMemory(GX2RResourceFlags resourceFlags, void *pMem, u32 byteCount); /// \brief Utility function to perform correct cache invalidation for the specified buffer /// /// \param gx2Buffer Address of a \ref GX2RBuffer struct. /// \param optionFlags The OPTION values are used instead of buffer resourceFlags (that is buffer NO_INVALIDATE flags will be ignored) /// /// \note Typically when using the GX2R APIs this will not be necessary, however it is useful when using \ref GX2RResourceFlags /// to suppress invalidation within the API. /// See also \ref GX2RInvalidateMemory /// /// \donotcall \gx2_typical \enddonotcall /// /// \writesgpu /// \writesgpu{if the buffer resource usage is any GPU usable type (for example, \ref GX2R_BIND_VERTEX_BUFFER)} /// void GX2API GX2RInvalidateBuffer(const GX2RBuffer* gx2Buffer, GX2RResourceFlags optionFlags); /// \brief Get the size of the guard bands required for a buffer with the specified flags. /// \param resourceFlags Type/semantics/options for the data referenced by pMem /// /// \note This function is a static calculation and does not take into account whether guard bands are currently enabled - if required /// that can be queried with \ref GX2RGetDebugOptions. /// If the resourceFlags are from a buffer created with \ref GX2RCreateBufferUserMemory the return value will be zero. /// To ignore the user memory status, mask out the GX2R_RESOURCE_FLAG_RESERVED bits. /// /// \donotcall \threadsafe \devonly \enddonotcall /// u32 GX2API GX2RGetBufferGuardBandSize(GX2RResourceFlags resourceFlags); /// @} #ifdef __cplusplus } #endif // __cplusplus #endif // _CAFE_GX2R_BUFFER_H_