diff options
-rw-r--r-- | o3d/command_buffer/common/cross/cmd_buffer_format.h | 627 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/cmd_parser.h | 2 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gapi_decoder.cc | 1243 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/gapi_decoder.h | 14 | ||||
-rw-r--r-- | o3d/command_buffer/service/cross/mocks.h | 14 |
5 files changed, 1254 insertions, 646 deletions
diff --git a/o3d/command_buffer/common/cross/cmd_buffer_format.h b/o3d/command_buffer/common/cross/cmd_buffer_format.h index 1338329..51d0e9b 100644 --- a/o3d/command_buffer/common/cross/cmd_buffer_format.h +++ b/o3d/command_buffer/common/cross/cmd_buffer_format.h @@ -38,6 +38,7 @@ #include "base/basictypes.h" #include "command_buffer/common/cross/types.h" #include "command_buffer/common/cross/bitfield_helpers.h" +#include "core/cross/packing.h" namespace o3d { namespace command_buffer { @@ -268,74 +269,572 @@ typedef BitField<30, 1> SeparateAlpha; typedef BitField<31, 1> Enable; } // namespace set_blending + +// This macro is used to safely and convienently expand the list of commnad +// buffer commands in to various lists and never have them get out of sync. To +// add a new command, add it this list, create the corresponding structure below +// and then add a function in gapi_decoder.cc called Handle_COMMAND_NAME where +// COMMAND_NAME is the name of your command structure. +// +// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order) +#define O3D_COMMAND_BUFFER_CMDS \ + O3D_COMMAND_BUFFER_CMD_OP(NOOP) /* 0 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TOKEN) \ + O3D_COMMAND_BUFFER_CMD_OP(BEGIN_FRAME) \ + O3D_COMMAND_BUFFER_CMD_OP(END_FRAME) \ + O3D_COMMAND_BUFFER_CMD_OP(CLEAR) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_VERTEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_VERTEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_BUFFER_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_VERTEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_INDEX_BUFFER) /* 10 */ \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_INDEX_BUFFER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_INDEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_INDEX_BUFFER_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_INDEX_BUFFER_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_INPUT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VERTEX_STRUCT) \ + O3D_COMMAND_BUFFER_CMD_OP(DRAW) \ + O3D_COMMAND_BUFFER_CMD_OP(DRAW_INDEXED) /* 20 */ \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_EFFECT_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_EFFECT) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_PARAM_COUNT) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM_BY_NAME) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_PARAM_BY_NAME_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_PARAM) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_PARAM_DATA) /* 30 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_PARAM_DATA_IMMEDIATE) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_PARAM_DESC) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_STREAM_COUNT) \ + O3D_COMMAND_BUFFER_CMD_OP(GET_STREAM_DESC) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_TEXTURE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_2D) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_3D) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_TEXTURE_CUBE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TEXTURE_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_TEXTURE_DATA_IMMEDIATE) /* 40 */ \ + O3D_COMMAND_BUFFER_CMD_OP(GET_TEXTURE_DATA) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_SAMPLER) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_SAMPLER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_STATES) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_BORDER_COLOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SAMPLER_TEXTURE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_VIEWPORT) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_SCISSOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POINT_LINE_RASTER) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POLYGON_RASTER) /* 50 */ \ + O3D_COMMAND_BUFFER_CMD_OP(SET_POLYGON_OFFSET) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_ALPHA_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_DEPTH_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_STENCIL_TEST) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BLENDING) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BLENDING_COLOR) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_COLOR_WRITE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(CREATE_DEPTH_SURFACE) /* 60 */ \ + O3D_COMMAND_BUFFER_CMD_OP(DESTROY_DEPTH_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_RENDER_SURFACE) \ + O3D_COMMAND_BUFFER_CMD_OP(SET_BACK_SURFACES) \ + + // GAPI commands. enum CommandId { - NOOP, // No operation. Arbitrary argument size. - SET_TOKEN, // Sets token. 1 argument. val 0 - BEGIN_FRAME, // BeginFrame. 0 argument. - END_FRAME, // EndFrame. 0 argument. - CLEAR, // Clear. 7 arguments. - CREATE_VERTEX_BUFFER, // CreateVertexBuffer, 3 arguments. - DESTROY_VERTEX_BUFFER, // DestroyVertexBuffer. 1 argument. - SET_VERTEX_BUFFER_DATA, // SetVertexBufferData, 5 args - SET_VERTEX_BUFFER_DATA_IMMEDIATE, // SetVertexBufferData, 2 args + data - GET_VERTEX_BUFFER_DATA, // GetVertexBufferData, 5 args, - CREATE_INDEX_BUFFER, // CreateIndexBuffer, 3 arguments. val 10 - DESTROY_INDEX_BUFFER, // DestroyIndexBuffer. 1 argument. - SET_INDEX_BUFFER_DATA, // SetIndexBufferData, 5 args - SET_INDEX_BUFFER_DATA_IMMEDIATE, // SetIndexBufferData, 2 args + data - GET_INDEX_BUFFER_DATA, // GetIndexBufferData, 5 args - CREATE_VERTEX_STRUCT, // CreateVertexStruct, 2 args. - DESTROY_VERTEX_STRUCT, // DestroyVertexStruct. 1 argument. - SET_VERTEX_INPUT, // SetVertexInput, 5 args. - SET_VERTEX_STRUCT, // SetVertexStruct, 1 arg. - DRAW, // Draw, 3 args. value - DRAW_INDEXED, // DrawIndexed, 6 args. val 20 - CREATE_EFFECT, // CreateEffect, 4 args. - CREATE_EFFECT_IMMEDIATE, // CreateEffect, 2 args + data - DESTROY_EFFECT, // DestroyEffect, 1 arg. - SET_EFFECT, // SetEffect, 1 arg. - GET_PARAM_COUNT, // GetParamCount, 4 args. - CREATE_PARAM, // CreateParam, 3 args. - CREATE_PARAM_BY_NAME, // CreateParamByName, 5 args. - CREATE_PARAM_BY_NAME_IMMEDIATE, // CreateParamByName, 3 args + data - DESTROY_PARAM, // DestroyParam, 1 arg - SET_PARAM_DATA, // SetParamData, 4 args val 30 - SET_PARAM_DATA_IMMEDIATE, // SetParamData, 2 args + data - GET_PARAM_DESC, // GetParamDesc, 4 args - GET_STREAM_COUNT, // GetStreamCount, 4 args. - GET_STREAM_DESC, // GetStreamDesc, 5 args - DESTROY_TEXTURE, // DestroyTexture, 1 arg - CREATE_TEXTURE_2D, // CreateTexture2D, 4 args - CREATE_TEXTURE_3D, // CreateTexture3D, 4 args - CREATE_TEXTURE_CUBE, // CreateTextureCube, 3 args - SET_TEXTURE_DATA, // SetTextureData, 10 args - SET_TEXTURE_DATA_IMMEDIATE, // SetTextureData, 8 args + data val 40 - GET_TEXTURE_DATA, // GetTextureData, 10 args - CREATE_SAMPLER, // CreateSampler, 1 arg - DESTROY_SAMPLER, // DestroySampler, 1 arg - SET_SAMPLER_STATES, // SetSamplerStates, 2 arg - SET_SAMPLER_BORDER_COLOR, // SetSamplerBorderColor, 5 arg - SET_SAMPLER_TEXTURE, // SetSamplerTexture, 2 arg - SET_VIEWPORT, // SetViewport. 6 arguments. - SET_SCISSOR, // SetScissor, 2 args - SET_POINT_LINE_RASTER, // SetPointLineRaster, 2 args - SET_POLYGON_RASTER, // SetPolygonRaster, 1 args val 50 - SET_POLYGON_OFFSET, // SetPolygonOffest, 2 args - SET_ALPHA_TEST, // SetAlphaTest, 2 args - SET_DEPTH_TEST, // SetDepthTest, 1 args - SET_STENCIL_TEST, // SetStencilTest, 2 args - SET_BLENDING, // SetBlending, 1 args - SET_BLENDING_COLOR, // SetBlendingColor, 4 args - SET_COLOR_WRITE, // SetColorWrite, 1 args - CREATE_RENDER_SURFACE, // CreateRenderSurface, 4 args. - DESTROY_RENDER_SURFACE, // DestoryRenderSurface, 1 arg. - CREATE_DEPTH_SURFACE, // CreateRenderSurface, 2 args. val 60 - DESTROY_DEPTH_SURFACE, // DestoryRenderSurface, 1 arg. - SET_RENDER_SURFACE, // SetRenderSurface, 2 args. - SET_BACK_SURFACES // SetBackSurfaces + #define O3D_COMMAND_BUFFER_CMD_OP(name) name, + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP +}; + +namespace cmd { + +// Make sure the compiler does not add extra padding to any of the command +// structures. +O3D_PUSH_STRUCTURE_PACKING_1; + +enum ArgFlags { + kFixed = 0x0, + kAtLeastN = 0x1, +}; + +struct SharedMemory { + uint32 id; + uint32 offset; +}; + +struct NOOP { + static const CommandId kCmdId = command_buffer::NOOP; + static const ArgFlags kArgFlags = kAtLeastN; +}; + +struct SET_TOKEN { + static const CommandId kCmdId = command_buffer::SET_TOKEN; + static const ArgFlags kArgFlags = kFixed; + uint32 token; +}; + +struct BEGIN_FRAME { + static const CommandId kCmdId = command_buffer::BEGIN_FRAME; + static const ArgFlags kArgFlags = kFixed; +}; + +struct END_FRAME { + static const CommandId kCmdId = command_buffer::END_FRAME; + static const ArgFlags kArgFlags = kFixed; +}; + +struct CLEAR { + static const CommandId kCmdId = command_buffer::CLEAR; + static const ArgFlags kArgFlags = kFixed; + uint32 buffers; + float red; + float green; + float blue; + float alpha; + float depth; + uint32 stencil; +}; + +struct SET_VIEWPORT { + static const CommandId kCmdId = command_buffer::SET_VIEWPORT; + static const ArgFlags kArgFlags = kFixed; + uint32 left; + uint32 top; + uint32 width; + uint32 height; + float z_min; + float z_max; +}; + +struct CREATE_VERTEX_BUFFER { + static const CommandId kCmdId = command_buffer::CREATE_VERTEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + uint32 flags; +}; + +struct DESTROY_VERTEX_BUFFER { + static const CommandId kCmdId = command_buffer::DESTROY_VERTEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_VERTEX_BUFFER_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_VERTEX_BUFFER_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 offset; +}; + +struct SET_VERTEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::SET_VERTEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_VERTEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::GET_VERTEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_INDEX_BUFFER { + static const CommandId kCmdId = command_buffer::CREATE_INDEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + uint32 flags; +}; + +struct DESTROY_INDEX_BUFFER { + static const CommandId kCmdId = command_buffer::DESTROY_INDEX_BUFFER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_INDEX_BUFFER_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_INDEX_BUFFER_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 offset; +}; + +struct SET_INDEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::SET_INDEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_INDEX_BUFFER_DATA { + static const CommandId kCmdId = command_buffer::GET_INDEX_BUFFER_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 offset; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::CREATE_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 input_count; +}; + +struct DESTROY_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::DESTROY_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_VERTEX_INPUT { + static const CommandId kCmdId = command_buffer::SET_VERTEX_INPUT; + static const ArgFlags kArgFlags = kAtLeastN; +}; + +struct SET_VERTEX_STRUCT { + static const CommandId kCmdId = command_buffer::SET_VERTEX_STRUCT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct DRAW { + static const CommandId kCmdId = command_buffer::DRAW; + static const ArgFlags kArgFlags = kFixed; + uint32 primitive_type; + uint32 first; + uint32 count; +}; + +struct DRAW_INDEXED { + static const CommandId kCmdId = command_buffer::DRAW_INDEXED; + static const ArgFlags kArgFlags = kFixed; + uint32 primitive_type; + uint32 index_buffer_id; + uint32 first; + uint32 count; + uint32 min_index; + uint32 max_index; +}; + +struct CREATE_EFFECT { + static const CommandId kCmdId = command_buffer::CREATE_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_EFFECT_IMMEDIATE { + static const CommandId kCmdId = command_buffer::CREATE_EFFECT_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 size; +}; + +struct DESTROY_EFFECT { + static const CommandId kCmdId = command_buffer::DESTROY_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_EFFECT { + static const CommandId kCmdId = command_buffer::SET_EFFECT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct GET_PARAM_COUNT { + static const CommandId kCmdId = command_buffer::GET_PARAM_COUNT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_PARAM { + static const CommandId kCmdId = command_buffer::CREATE_PARAM; + static const ArgFlags kArgFlags = kFixed; + uint32 param_id; + uint32 effect_id; + uint32 index; +}; + +struct CREATE_PARAM_BY_NAME { + static const CommandId kCmdId = command_buffer::CREATE_PARAM_BY_NAME; + static const ArgFlags kArgFlags = kFixed; + uint32 param_id; + uint32 effect_id; + uint32 size; + SharedMemory shared_memory; +}; + +struct CREATE_PARAM_BY_NAME_IMMEDIATE { + static const CommandId kCmdId = command_buffer::CREATE_PARAM_BY_NAME_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 param_id; + uint32 effect_id; + uint32 size; }; +struct DESTROY_PARAM { + static const CommandId kCmdId = command_buffer::DESTROY_PARAM; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_PARAM_DATA { + static const CommandId kCmdId = command_buffer::SET_PARAM_DATA; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct SET_PARAM_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_PARAM_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + uint32 id; + uint32 size; +}; + +struct GET_PARAM_DESC { + static const CommandId kCmdId = command_buffer::GET_PARAM_DESC; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_STREAM_COUNT { + static const CommandId kCmdId = command_buffer::GET_STREAM_COUNT; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 size; + SharedMemory shared_memory; +}; + +struct GET_STREAM_DESC { + static const CommandId kCmdId = command_buffer::GET_STREAM_DESC; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 index; + uint32 size; + SharedMemory shared_memory; +}; + +struct DESTROY_TEXTURE { + static const CommandId kCmdId = command_buffer::DESTROY_TEXTURE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct CREATE_TEXTURE_2D { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_2D; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_TEXTURE_3D { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_3D; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_TEXTURE_CUBE { + static const CommandId kCmdId = command_buffer::CREATE_TEXTURE_CUBE; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_TEXTURE_DATA { + static const CommandId kCmdId = command_buffer::SET_TEXTURE_DATA; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_TEXTURE_DATA_IMMEDIATE { + static const CommandId kCmdId = command_buffer::SET_TEXTURE_DATA_IMMEDIATE; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct GET_TEXTURE_DATA { + static const CommandId kCmdId = command_buffer::GET_TEXTURE_DATA; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct CREATE_SAMPLER { + static const CommandId kCmdId = command_buffer::CREATE_SAMPLER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct DESTROY_SAMPLER { + static const CommandId kCmdId = command_buffer::DESTROY_SAMPLER; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_SAMPLER_STATES { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_STATES; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_SAMPLER_BORDER_COLOR { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_BORDER_COLOR; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + float red; + float blue; + float green; + float alpha; +}; + +struct SET_SAMPLER_TEXTURE { + static const CommandId kCmdId = command_buffer::SET_SAMPLER_TEXTURE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; + uint32 texture_id; +}; + +struct SET_SCISSOR { + static const CommandId kCmdId = command_buffer::SET_SCISSOR; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + uint32 fixme1; +}; + +struct SET_POLYGON_OFFSET { + static const CommandId kCmdId = command_buffer::SET_POLYGON_OFFSET; + static const ArgFlags kArgFlags = kFixed; + float slope_factor; + float units; +}; + +struct SET_POINT_LINE_RASTER { + static const CommandId kCmdId = command_buffer::SET_POINT_LINE_RASTER; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + float point_size; +}; + +struct SET_POLYGON_RASTER { + static const CommandId kCmdId = command_buffer::SET_POLYGON_RASTER; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; +}; + +struct SET_ALPHA_TEST { + static const CommandId kCmdId = command_buffer::SET_ALPHA_TEST; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; + float value; +}; + +struct SET_DEPTH_TEST { + static const CommandId kCmdId = command_buffer::SET_DEPTH_TEST; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 fixme0; +}; + +struct SET_STENCIL_TEST { + static const CommandId kCmdId = command_buffer::SET_STENCIL_TEST; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_COLOR_WRITE { + static const CommandId kCmdId = command_buffer::SET_COLOR_WRITE; + static const ArgFlags kArgFlags = kFixed; + uint32 flags; +}; + +struct SET_BLENDING { + static const CommandId kCmdId = command_buffer::SET_BLENDING; + static const ArgFlags kArgFlags = kAtLeastN; + // TODO(gman): fix this to not use obfusticated fields. +}; + +struct SET_BLENDING_COLOR { + static const CommandId kCmdId = command_buffer::SET_BLENDING_COLOR; + static const ArgFlags kArgFlags = kFixed; + float red; + float blue; + float green; + float alpha; +}; + +struct CREATE_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::CREATE_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 id; + uint32 fixme1; + uint32 fixme2; + uint32 texture_id; +}; + +struct DESTROY_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::DESTROY_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct CREATE_DEPTH_SURFACE { + static const CommandId kCmdId = command_buffer::CREATE_DEPTH_SURFACE; + static const ArgFlags kArgFlags = kFixed; + // TODO(gman): fix this to not use obfusticated fields. + uint32 id; + uint32 fixme1; +}; + +struct DESTROY_DEPTH_SURFACE { + static const CommandId kCmdId = command_buffer::DESTROY_DEPTH_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 id; +}; + +struct SET_RENDER_SURFACE { + static const CommandId kCmdId = command_buffer::SET_RENDER_SURFACE; + static const ArgFlags kArgFlags = kFixed; + uint32 render_surface_id; + uint32 depth_surface_id; +}; + +struct SET_BACK_SURFACES { + static const CommandId kCmdId = command_buffer::SET_BACK_SURFACES; + static const ArgFlags kArgFlags = kFixed; +}; + +O3D_POP_STRUCTURE_PACKING; + +} // namespace cmd + } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/service/cross/cmd_parser.h b/o3d/command_buffer/service/cross/cmd_parser.h index 511e52b..9c3a145 100644 --- a/o3d/command_buffer/service/cross/cmd_parser.h +++ b/o3d/command_buffer/service/cross/cmd_parser.h @@ -104,7 +104,7 @@ class AsyncAPIInterface { virtual BufferSyncInterface::ParseError DoCommand( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) = 0; + const void* args) = 0; }; } // namespace command_buffer diff --git a/o3d/command_buffer/service/cross/gapi_decoder.cc b/o3d/command_buffer/service/cross/gapi_decoder.cc index 3087733..47a3418 100644 --- a/o3d/command_buffer/service/cross/gapi_decoder.cc +++ b/o3d/command_buffer/service/cross/gapi_decoder.cc @@ -41,6 +41,40 @@ namespace o3d { namespace command_buffer { +namespace { + +template <typename T> +const void* AddressAfterStruct(const T& pod) { + return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); +} + +template <typename T> +unsigned int ImmediateSize(uint32 arg_count, const T& pod) { + return (arg_count - sizeof(pod) / sizeof(uint32)) * sizeof(uint32); +} + +// TODO(gman): Remove this. +CommandBufferEntry* TempHack(const void* foo) { + return reinterpret_cast<CommandBufferEntry*>(const_cast<void*>(foo)); +} + +struct CommandInfo { + int arg_flags; + int arg_count; +}; + +const CommandInfo g_command_info[] = { + #define O3D_COMMAND_BUFFER_CMD_OP(name) { \ + cmd::name::kArgFlags, \ + sizeof(cmd::name) / sizeof(uint32), }, \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP +}; + +} // anonymous namespace. + // Decode command with its arguments, and call the corresponding GAPIInterface // method. // Note: args is a pointer to the command buffer. As such, it could be changed @@ -49,586 +83,30 @@ namespace command_buffer { BufferSyncInterface::ParseError GAPIDecoder::DoCommand( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) { - switch (command) { - case NOOP: - return BufferSyncInterface::PARSE_NO_ERROR; - case SET_TOKEN: - if (arg_count == 1) { - engine_->set_token(args[0].value_uint32); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case BEGIN_FRAME: - if (arg_count == 0) { - gapi_->BeginFrame(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case END_FRAME: - if (arg_count == 0) { - gapi_->EndFrame(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CLEAR: - if (arg_count == 7) { - unsigned int buffers = args[0].value_uint32; - if (buffers & ~GAPIInterface::ALL_BUFFERS) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - RGBA rgba; - rgba.red = args[1].value_float; - rgba.green = args[2].value_float; - rgba.blue = args[3].value_float; - rgba.alpha = args[4].value_float; - float depth = args[5].value_float; - unsigned int stencil = args[6].value_uint32; - gapi_->Clear(buffers, rgba, depth, stencil); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VIEWPORT: - if (arg_count == 6) { - gapi_->SetViewport(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32, - args[3].value_uint32, - args[4].value_float, - args[5].value_float); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_VERTEX_BUFFER: - if (arg_count == 3) { - return gapi_->CreateVertexBuffer(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_VERTEX_BUFFER: - if (arg_count == 1) { - return gapi_->DestroyVertexBuffer(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VERTEX_BUFFER_DATA_IMMEDIATE: { - if (arg_count < 2) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = (arg_count - 2) * sizeof(args[0]); - return gapi_->SetVertexBufferData(id, offset, size, args + 2); - } - case SET_VERTEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetVertexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_VERTEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetVertexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_INDEX_BUFFER: - if (arg_count == 3) { - return gapi_->CreateIndexBuffer(args[0].value_uint32, - args[1].value_uint32, - args[2].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_INDEX_BUFFER: - if (arg_count == 1) { - return gapi_->DestroyIndexBuffer(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + const void* args) { + if (command < arraysize(g_command_info)) { + const CommandInfo& info = g_command_info[command]; + if ((info.arg_flags == cmd::kFixed && arg_count == info.arg_count) || + (info.arg_flags == cmd::kAtLeastN && arg_count > info.arg_count)) { + switch (command) { + #define O3D_COMMAND_BUFFER_CMD_OP(name) \ + case cmd::name::kCmdId: \ + return Handle_ ## name( \ + arg_count, \ + *static_cast<const cmd::name*>(args)); \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP } - case SET_INDEX_BUFFER_DATA_IMMEDIATE: { - if (arg_count < 2) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = (arg_count - 2) * sizeof(args[0]); - return gapi_->SetIndexBufferData(id, offset, size, args + 2); + } else { + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; } - case SET_INDEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetIndexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_INDEX_BUFFER_DATA: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int offset = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetIndexBufferData(id, offset, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_VERTEX_STRUCT: - if (arg_count == 2) { - return gapi_->CreateVertexStruct(args[0].value_uint32, - args[1].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_VERTEX_STRUCT: - if (arg_count == 1) { - return gapi_->DestroyVertexStruct(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_VERTEX_INPUT: - return DecodeSetVertexInput(arg_count, args); - case SET_VERTEX_STRUCT: - if (arg_count == 1) { - return gapi_->SetVertexStruct(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DRAW: - if (arg_count == 3) { - unsigned int primitive_type = args[0].value_uint32; - if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - unsigned int first = args[1].value_uint32; - unsigned int count = args[2].value_uint32; - return gapi_->Draw( - static_cast<GAPIInterface::PrimitiveType>(primitive_type), - first, count); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DRAW_INDEXED: - if (arg_count == 6) { - unsigned int primitive_type = args[0].value_uint32; - if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - ResourceID index_buffer = args[1].value_uint32; - unsigned int first = args[2].value_uint32; - unsigned int count = args[3].value_uint32; - unsigned int min_index = args[4].value_uint32; - unsigned int max_index = args[5].value_uint32; - return gapi_->DrawIndexed( - static_cast<GAPIInterface::PrimitiveType>(primitive_type), - index_buffer, first, count, min_index, max_index); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_EFFECT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateEffect(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_EFFECT_IMMEDIATE: - if (arg_count > 2) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - if (size > (arg_count-2) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateEffect(id, size, args + 2); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_EFFECT: - if (arg_count == 1) { - return gapi_->DestroyEffect(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_EFFECT: - if (arg_count == 1) { - return gapi_->SetEffect(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_PARAM_COUNT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetParamCount(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM: - if (arg_count == 3) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int index = args[2].value_uint32; - return gapi_->CreateParam(param_id, effect_id, index); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM_BY_NAME: - if (arg_count == 5) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateParamByName(param_id, effect_id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_PARAM_BY_NAME_IMMEDIATE: - if (arg_count > 3) { - ResourceID param_id = args[0].value_uint32; - ResourceID effect_id = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - if (size > (arg_count-1) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->CreateParamByName(param_id, effect_id, size, args + 3); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_PARAM: - if (arg_count == 1) { - return gapi_->DestroyParam(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_PARAM_DATA: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetParamData(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_PARAM_DATA_IMMEDIATE: - if (arg_count > 2) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - if (size > (arg_count-2) * sizeof(args[0])) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->SetParamData(id, size, args + 2); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_PARAM_DESC: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetParamDesc(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_STREAM_COUNT: - if (arg_count == 4) { - ResourceID id = args[0].value_uint32; - unsigned int size = args[1].value_uint32; - void *data = GetAddressAndCheckSize(args[2].value_uint32, - args[3].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetStreamCount(id, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case GET_STREAM_DESC: - if (arg_count == 5) { - ResourceID id = args[0].value_uint32; - unsigned int index = args[1].value_uint32; - unsigned int size = args[2].value_uint32; - void *data = GetAddressAndCheckSize(args[3].value_uint32, - args[4].value_uint32, - size); - if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - return gapi_->GetStreamDesc(id, index, size, data); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_TEXTURE: - if (arg_count == 1) { - return gapi_->DestroyTexture(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_TEXTURE_2D: - return DecodeCreateTexture2D(arg_count, args); - case CREATE_TEXTURE_3D: - return DecodeCreateTexture3D(arg_count, args); - case CREATE_TEXTURE_CUBE: - return DecodeCreateTextureCube(arg_count, args); - case SET_TEXTURE_DATA: - return DecodeSetTextureData(arg_count, args); - case SET_TEXTURE_DATA_IMMEDIATE: - return DecodeSetTextureDataImmediate(arg_count, args); - case GET_TEXTURE_DATA: - return DecodeGetTextureData(arg_count, args); - case CREATE_SAMPLER: - if (arg_count == 1) { - return gapi_->CreateSampler(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_SAMPLER: - if (arg_count == 1) { - return gapi_->DestroySampler(args[0].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SAMPLER_STATES: - return DecodeSetSamplerStates(arg_count, args); - case SET_SAMPLER_BORDER_COLOR: - if (arg_count == 5) { - RGBA rgba; - rgba.red = args[1].value_float; - rgba.green = args[2].value_float; - rgba.blue = args[3].value_float; - rgba.alpha = args[4].value_float; - return gapi_->SetSamplerBorderColor(args[0].value_uint32, rgba); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SAMPLER_TEXTURE: - if (arg_count == 2) { - return gapi_->SetSamplerTexture(args[0].value_uint32, - args[1].value_uint32); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_SCISSOR: - if (arg_count == 2) { - namespace cmd = set_scissor; - Uint32 x_y_enable = args[0].value_uint32; - if (cmd::Unused::Get(x_y_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - unsigned int x = cmd::X::Get(x_y_enable); - unsigned int y = cmd::Y::Get(x_y_enable); - bool enable = cmd::Enable::Get(x_y_enable) != 0; - Uint32 width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - gapi_->SetScissor(enable, x, y, width, height); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POLYGON_OFFSET: - if (arg_count == 2) { - gapi_->SetPolygonOffset(args[0].value_float, args[1].value_float); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POINT_LINE_RASTER: - if (arg_count == 2) { - namespace cmd = set_point_line_raster; - Uint32 enables = args[0].value_uint32; - if (cmd::Unused::Get(enables) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // !! to convert int to bool in a way that does not generate a - // warning in visual studio. - bool line_smooth = !!cmd::LineSmoothEnable::Get(enables); - bool point_sprite = !!cmd::PointSpriteEnable::Get(enables); - float point_size = args[1].value_float; - gapi_->SetPointLineRaster(line_smooth, point_sprite, point_size); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_POLYGON_RASTER: - if (arg_count == 1) { - namespace cmd = set_polygon_raster; - Uint32 fill_cull = args[0].value_uint32; - unsigned int fill_value = cmd::FillMode::Get(fill_cull); - unsigned int cull_value = cmd::CullMode::Get(fill_cull); - if (cmd::Unused::Get(fill_cull) != 0 || - fill_value >= GAPIInterface::NUM_POLYGON_MODE || - cull_value >= GAPIInterface::NUM_FACE_CULL_MODE) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - gapi_->SetPolygonRaster( - static_cast<GAPIInterface::PolygonMode>(fill_value), - static_cast<GAPIInterface::FaceCullMode>(cull_value)); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_ALPHA_TEST: - if (arg_count == 2) { - namespace cmd = set_alpha_test; - Uint32 func_enable = args[0].value_uint32; - if (cmd::Unused::Get(func_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, - set_alpha_test_Func_may_produce_invalid_values); - GAPIInterface::Comparison comp = - static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); - bool enable = cmd::Enable::Get(func_enable) != 0; - gapi_->SetAlphaTest(enable, args[1].value_float, comp); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_DEPTH_TEST: - if (arg_count == 1) { - namespace cmd = set_depth_test; - Uint32 func_enable = args[0].value_uint32; - if (cmd::Unused::Get(func_enable) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - // Check that the bitmask get cannot generate values outside of the - // allowed range. - COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, - set_alpha_test_Func_may_produce_invalid_values); - GAPIInterface::Comparison comp = - static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); - bool write_enable = cmd::WriteEnable::Get(func_enable) != 0; - bool enable = cmd::Enable::Get(func_enable) != 0; - gapi_->SetDepthTest(enable, write_enable, comp); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_STENCIL_TEST: - return DecodeSetStencilTest(arg_count, args); - case SET_COLOR_WRITE: - if (arg_count == 1) { - namespace cmd = set_color_write; - Uint32 enables = args[0].value_uint32; - if (cmd::Unused::Get(enables) != 0) - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - bool red = cmd::RedMask::Get(enables) != 0; - bool green = cmd::GreenMask::Get(enables) != 0; - bool blue = cmd::BlueMask::Get(enables) != 0; - bool alpha = cmd::AlphaMask::Get(enables) != 0; - bool dither = cmd::DitherEnable::Get(enables) != 0; - gapi_->SetColorWrite(red, green, blue, alpha, dither); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_BLENDING: - return DecodeSetBlending(arg_count, args); - case SET_BLENDING_COLOR: - if (arg_count == 4) { - RGBA rgba; - rgba.red = args[0].value_float; - rgba.green = args[1].value_float; - rgba.blue = args[2].value_float; - rgba.alpha = args[3].value_float; - gapi_->SetBlendingColor(rgba); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_RENDER_SURFACE: - if (arg_count == 4) { - namespace cmd = create_render_surface_cmd; - ResourceID id = args[0].value_uint32; - unsigned int width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - unsigned int levels_side = args[2].value_uint32; - unsigned int mip_level = cmd::Levels::Get(levels_side); - unsigned int side = cmd::Side::Get(levels_side); - ResourceID texture_id = args[3].value_uint32; - return gapi_->CreateRenderSurface(id, width, height, mip_level, - side, texture_id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_RENDER_SURFACE: - if (arg_count == 1) { - ResourceID id = args[0].value_uint32; - return gapi_->DestroyRenderSurface(id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case CREATE_DEPTH_SURFACE: - if (arg_count == 2) { - namespace cmd = create_render_surface_cmd; - ResourceID id = args[0].value_uint32; - unsigned int width_height = args[1].value_uint32; - unsigned int width = cmd::Width::Get(width_height); - unsigned int height = cmd::Height::Get(width_height); - return gapi_->CreateDepthSurface(id, width, height); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case DESTROY_DEPTH_SURFACE: - if (arg_count == 1) { - ResourceID id = args[0].value_uint32; - return gapi_->DestroyDepthSurface(id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_RENDER_SURFACE: - if (arg_count == 2) { - ResourceID render_surface_id = args[0].value_uint32; - ResourceID depth_stencil_id = args[1].value_uint32; - return gapi_->SetRenderSurface(render_surface_id, depth_stencil_id); - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - case SET_BACK_SURFACES: - if (arg_count == 0) { - gapi_->SetBackSurfaces(); - return BufferSyncInterface::PARSE_NO_ERROR; - } else { - return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; - } - default: - return BufferSyncInterface::PARSE_UNKNOWN_COMMAND; } + return BufferSyncInterface::PARSE_UNKNOWN_COMMAND; } + // Decodes the SET_VERTEX_INPUT command. BufferSyncInterface::ParseError GAPIDecoder::DecodeSetVertexInput( unsigned int arg_count, @@ -965,5 +443,620 @@ void *GAPIDecoder::GetAddressAndCheckSize(unsigned int shm_id, return static_cast<char *>(shm_addr) + offset; } +BufferSyncInterface::ParseError GAPIDecoder::Handle_NOOP( + uint32 arg_count, + const cmd::NOOP& args) { + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TOKEN( + uint32 arg_count, + const cmd::SET_TOKEN& args) { + engine_->set_token(args.token); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_BEGIN_FRAME( + uint32 arg_count, + const cmd::BEGIN_FRAME& args) { + gapi_->BeginFrame(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_END_FRAME( + uint32 arg_count, + const cmd::END_FRAME& args) { + gapi_->EndFrame(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CLEAR( + uint32 arg_count, + const cmd::CLEAR& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 buffers = args.buffers; + if (buffers & ~GAPIInterface::ALL_BUFFERS) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->Clear(buffers, rgba, args.depth, args.stencil); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VIEWPORT( + uint32 arg_count, + const cmd::SET_VIEWPORT& args) { + gapi_->SetViewport(args.left, + args.top, + args.width, + args.height, + args.z_min, + args.z_max); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_VERTEX_BUFFER( + uint32 arg_count, + const cmd::CREATE_VERTEX_BUFFER& args) { + return gapi_->CreateVertexBuffer(args.id, args.size, args.flags); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_VERTEX_BUFFER( + uint32 arg_count, + const cmd::DESTROY_VERTEX_BUFFER& args) { + return gapi_->DestroyVertexBuffer(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_BUFFER_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_VERTEX_BUFFER_DATA_IMMEDIATE& args) { + return gapi_->SetVertexBufferData(args.id, args.offset, + ImmediateSize(arg_count, args), + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_BUFFER_DATA( + uint32 arg_count, + const cmd::SET_VERTEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetVertexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_VERTEX_BUFFER_DATA( + uint32 arg_count, + const cmd::GET_VERTEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetVertexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_INDEX_BUFFER( + uint32 arg_count, + const cmd::CREATE_INDEX_BUFFER& args) { + return gapi_->CreateIndexBuffer(args.id, args.size, args.flags); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_INDEX_BUFFER( + uint32 arg_count, + const cmd::DESTROY_INDEX_BUFFER& args) { + return gapi_->DestroyIndexBuffer(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_INDEX_BUFFER_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_INDEX_BUFFER_DATA_IMMEDIATE& args) { + return gapi_->SetIndexBufferData(args.id, args.offset, + ImmediateSize(arg_count, args), + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_INDEX_BUFFER_DATA( + uint32 arg_count, + const cmd::SET_INDEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetIndexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_INDEX_BUFFER_DATA( + uint32 arg_count, + const cmd::GET_INDEX_BUFFER_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetIndexBufferData(args.id, args.offset, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_VERTEX_STRUCT( + uint32 arg_count, + const cmd::CREATE_VERTEX_STRUCT& args) { + return gapi_->CreateVertexStruct(args.id, args.input_count); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_VERTEX_STRUCT( + uint32 arg_count, + const cmd::DESTROY_VERTEX_STRUCT& args) { + return gapi_->DestroyVertexStruct(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_INPUT( + uint32 arg_count, + const cmd::SET_VERTEX_INPUT& args) { + // TODO(gman): fix. + return DecodeSetVertexInput(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_VERTEX_STRUCT( + uint32 arg_count, + const cmd::SET_VERTEX_STRUCT& args) { + return gapi_->SetVertexStruct(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DRAW( + uint32 arg_count, + const cmd::DRAW& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->Draw( + static_cast<GAPIInterface::PrimitiveType>(primitive_type), + args.first, args.count); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DRAW_INDEXED( + uint32 arg_count, + const cmd::DRAW_INDEXED& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 primitive_type = args.primitive_type; + if (primitive_type >= GAPIInterface::MAX_PRIMITIVE_TYPE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->DrawIndexed( + static_cast<GAPIInterface::PrimitiveType>(primitive_type), + args.index_buffer_id, + args.first, args.count, args.min_index, args.max_index); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_EFFECT( + uint32 arg_count, + const cmd::CREATE_EFFECT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateEffect(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_EFFECT_IMMEDIATE( + uint32 arg_count, + const cmd::CREATE_EFFECT_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateEffect(args.id, size, AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_EFFECT( + uint32 arg_count, + const cmd::DESTROY_EFFECT& args) { + return gapi_->DestroyEffect(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_EFFECT( + uint32 arg_count, + const cmd::SET_EFFECT& args) { + return gapi_->SetEffect(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_PARAM_COUNT( + uint32 arg_count, + const cmd::GET_PARAM_COUNT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetParamCount(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM( + uint32 arg_count, + const cmd::CREATE_PARAM& args) { + return gapi_->CreateParam(args.param_id, args.effect_id, args.index); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM_BY_NAME( + uint32 arg_count, + const cmd::CREATE_PARAM_BY_NAME& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_PARAM_BY_NAME_IMMEDIATE( + uint32 arg_count, + const cmd::CREATE_PARAM_BY_NAME_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->CreateParamByName(args.param_id, args.effect_id, size, + AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_PARAM( + uint32 arg_count, + const cmd::DESTROY_PARAM& args) { + return gapi_->DestroyParam(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_PARAM_DATA( + uint32 arg_count, + const cmd::SET_PARAM_DATA& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetParamData(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_PARAM_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_PARAM_DATA_IMMEDIATE& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + if (size > ImmediateSize(arg_count, args)) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->SetParamData(args.id, size, AddressAfterStruct(args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_PARAM_DESC( + uint32 arg_count, + const cmd::GET_PARAM_DESC& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetParamDesc(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_STREAM_COUNT( + uint32 arg_count, + const cmd::GET_STREAM_COUNT& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamCount(args.id, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_STREAM_DESC( + uint32 arg_count, + const cmd::GET_STREAM_DESC& args) { + // Pull out some values so they can't be changed by another thread after we've + // validated them. + uint32 size = args.size; + void *data = GetAddressAndCheckSize(args.shared_memory.id, + args.shared_memory.offset, + size); + if (!data) return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + return gapi_->GetStreamDesc(args.id, args.index, size, data); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_TEXTURE( + uint32 arg_count, + const cmd::DESTROY_TEXTURE& args) { + return gapi_->DestroyTexture(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_2D( + uint32 arg_count, + const cmd::CREATE_TEXTURE_2D& args) { + // TODO(gman): fix. + return DecodeCreateTexture2D(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_3D( + uint32 arg_count, + const cmd::CREATE_TEXTURE_3D& args) { + // TODO(gman): fix. + return DecodeCreateTexture3D(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_TEXTURE_CUBE( + uint32 arg_count, + const cmd::CREATE_TEXTURE_CUBE& args) { + // TODO(gman): fix. + return DecodeCreateTextureCube(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TEXTURE_DATA( + uint32 arg_count, + const cmd::SET_TEXTURE_DATA& args) { + // TODO(gman): fix. + return DecodeSetTextureData(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_TEXTURE_DATA_IMMEDIATE( + uint32 arg_count, + const cmd::SET_TEXTURE_DATA_IMMEDIATE& args) { + // TODO(gman): fix. + return DecodeSetTextureDataImmediate(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_GET_TEXTURE_DATA( + uint32 arg_count, + const cmd::GET_TEXTURE_DATA& args) { + // TODO(gman): fix. + return DecodeGetTextureData(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_SAMPLER( + uint32 arg_count, + const cmd::CREATE_SAMPLER& args) { + return gapi_->CreateSampler(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_SAMPLER( + uint32 arg_count, + const cmd::DESTROY_SAMPLER& args) { + return gapi_->DestroySampler(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_STATES( + uint32 arg_count, + const cmd::SET_SAMPLER_STATES& args) { + // TODO(gman): fix. + return DecodeSetSamplerStates(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_BORDER_COLOR( + uint32 arg_count, + const cmd::SET_SAMPLER_BORDER_COLOR& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + return gapi_->SetSamplerBorderColor(args.id, rgba); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SAMPLER_TEXTURE( + uint32 arg_count, + const cmd::SET_SAMPLER_TEXTURE& args) { + return gapi_->SetSamplerTexture(args.id, args.texture_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_SCISSOR( + uint32 arg_count, + const cmd::SET_SCISSOR& args) { + namespace cmd = set_scissor; + Uint32 x_y_enable = args.fixme0; + if (cmd::Unused::Get(x_y_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + unsigned int x = cmd::X::Get(x_y_enable); + unsigned int y = cmd::Y::Get(x_y_enable); + bool enable = cmd::Enable::Get(x_y_enable) != 0; + Uint32 width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + gapi_->SetScissor(enable, x, y, width, height); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POLYGON_OFFSET( + uint32 arg_count, + const cmd::SET_POLYGON_OFFSET& args) { + gapi_->SetPolygonOffset(args.slope_factor, args.units); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POINT_LINE_RASTER( + uint32 arg_count, + const cmd::SET_POINT_LINE_RASTER& args) { + namespace cmd = set_point_line_raster; + Uint32 enables = args.fixme0; + if (cmd::Unused::Get(enables) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + bool line_smooth = !!cmd::LineSmoothEnable::Get(enables); + bool point_sprite = !!cmd::PointSpriteEnable::Get(enables); + gapi_->SetPointLineRaster(line_smooth, point_sprite, args.point_size); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_POLYGON_RASTER( + uint32 arg_count, + const cmd::SET_POLYGON_RASTER& args) { + namespace cmd = set_polygon_raster; + Uint32 fill_cull = args.fixme0; + unsigned int fill_value = cmd::FillMode::Get(fill_cull); + unsigned int cull_value = cmd::CullMode::Get(fill_cull); + if (cmd::Unused::Get(fill_cull) != 0 || + fill_value >= GAPIInterface::NUM_POLYGON_MODE || + cull_value >= GAPIInterface::NUM_FACE_CULL_MODE) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + gapi_->SetPolygonRaster( + static_cast<GAPIInterface::PolygonMode>(fill_value), + static_cast<GAPIInterface::FaceCullMode>(cull_value)); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_ALPHA_TEST( + uint32 arg_count, + const cmd::SET_ALPHA_TEST& args) { + namespace cmd = set_alpha_test; + Uint32 func_enable = args.fixme0; + if (cmd::Unused::Get(func_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, + set_alpha_test_Func_may_produce_invalid_values); + GAPIInterface::Comparison comp = + static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); + bool enable = cmd::Enable::Get(func_enable) != 0; + gapi_->SetAlphaTest(enable, args.value, comp); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_DEPTH_TEST( + uint32 arg_count, + const cmd::SET_DEPTH_TEST& args) { + namespace cmd = set_depth_test; + Uint32 func_enable = args.fixme0; + if (cmd::Unused::Get(func_enable) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + // Check that the bitmask get cannot generate values outside of the + // allowed range. + COMPILE_ASSERT(cmd::Func::kMask < GAPIInterface::NUM_COMPARISON, + set_alpha_test_Func_may_produce_invalid_values); + GAPIInterface::Comparison comp = + static_cast<GAPIInterface::Comparison>(cmd::Func::Get(func_enable)); + bool write_enable = cmd::WriteEnable::Get(func_enable) != 0; + bool enable = cmd::Enable::Get(func_enable) != 0; + gapi_->SetDepthTest(enable, write_enable, comp); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_STENCIL_TEST( + uint32 arg_count, + const cmd::SET_STENCIL_TEST& args) { + // TODO(gman): fix. + return DecodeSetStencilTest(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_COLOR_WRITE( + uint32 arg_count, + const cmd::SET_COLOR_WRITE& args) { + namespace cmd = set_color_write; + Uint32 enables = args.flags; + if (cmd::Unused::Get(enables) != 0) + return BufferSyncInterface::PARSE_INVALID_ARGUMENTS; + bool red = cmd::RedMask::Get(enables) != 0; + bool green = cmd::GreenMask::Get(enables) != 0; + bool blue = cmd::BlueMask::Get(enables) != 0; + bool alpha = cmd::AlphaMask::Get(enables) != 0; + bool dither = cmd::DitherEnable::Get(enables) != 0; + gapi_->SetColorWrite(red, green, blue, alpha, dither); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BLENDING( + uint32 arg_count, + const cmd::SET_BLENDING& args) { + return DecodeSetBlending(arg_count, TempHack(&args)); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BLENDING_COLOR( + uint32 arg_count, + const cmd::SET_BLENDING_COLOR& args) { + RGBA rgba; + rgba.red = args.red; + rgba.green = args.green; + rgba.blue = args.blue; + rgba.alpha = args.alpha; + gapi_->SetBlendingColor(rgba); + return BufferSyncInterface::PARSE_NO_ERROR; +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_RENDER_SURFACE( + uint32 arg_count, + const cmd::CREATE_RENDER_SURFACE& args) { + namespace cmd = create_render_surface_cmd; + unsigned int width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + unsigned int levels_side = args.fixme2; + unsigned int mip_level = cmd::Levels::Get(levels_side); + unsigned int side = cmd::Side::Get(levels_side); + return gapi_->CreateRenderSurface(args.id, width, height, mip_level, + side, args.texture_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_RENDER_SURFACE( + uint32 arg_count, + const cmd::DESTROY_RENDER_SURFACE& args) { + return gapi_->DestroyRenderSurface(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_CREATE_DEPTH_SURFACE( + uint32 arg_count, + const cmd::CREATE_DEPTH_SURFACE& args) { + namespace cmd = create_render_surface_cmd; + unsigned int width_height = args.fixme1; + unsigned int width = cmd::Width::Get(width_height); + unsigned int height = cmd::Height::Get(width_height); + return gapi_->CreateDepthSurface(args.id, width, height); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_DESTROY_DEPTH_SURFACE( + uint32 arg_count, + const cmd::DESTROY_DEPTH_SURFACE& args) { + return gapi_->DestroyDepthSurface(args.id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_RENDER_SURFACE( + uint32 arg_count, + const cmd::SET_RENDER_SURFACE& args) { + return gapi_->SetRenderSurface(args.render_surface_id, args.depth_surface_id); +} + +BufferSyncInterface::ParseError GAPIDecoder::Handle_SET_BACK_SURFACES( + uint32 arg_count, + const cmd::SET_BACK_SURFACES& args) { + gapi_->SetBackSurfaces(); + return BufferSyncInterface::PARSE_NO_ERROR; +} + } // namespace command_buffer } // namespace o3d diff --git a/o3d/command_buffer/service/cross/gapi_decoder.h b/o3d/command_buffer/service/cross/gapi_decoder.h index 24d55e0..67b1806 100644 --- a/o3d/command_buffer/service/cross/gapi_decoder.h +++ b/o3d/command_buffer/service/cross/gapi_decoder.h @@ -62,7 +62,7 @@ class GAPIDecoder : public AsyncAPIInterface { // BufferSyncInterface::ParseError otherwise. virtual ParseError DoCommand(unsigned int command, unsigned int arg_count, - CommandBufferEntry *args); + const void* args); // Sets the engine, to get shared memory buffers from, and to set the token // to. @@ -121,6 +121,18 @@ class GAPIDecoder : public AsyncAPIInterface { void *GetAddressAndCheckSize(unsigned int shm_id, unsigned int offset, unsigned int size); + + // Generate a member function prototype for each command in an automated and + // typesafe way. + #define O3D_COMMAND_BUFFER_CMD_OP(name) \ + ParseError Handle_ ## name( \ + unsigned int arg_count, \ + const cmd::name& args); \ + + O3D_COMMAND_BUFFER_CMDS + + #undef O3D_COMMAND_BUFFER_CMD_OP + GAPIInterface *gapi_; CommandBufferEngine *engine_; }; diff --git a/o3d/command_buffer/service/cross/mocks.h b/o3d/command_buffer/service/cross/mocks.h index 3d150ee..353ff0c 100644 --- a/o3d/command_buffer/service/cross/mocks.h +++ b/o3d/command_buffer/service/cross/mocks.h @@ -58,11 +58,13 @@ class AsyncAPIMock : public AsyncAPIInterface { // Predicate that matches args passed to DoCommand, by looking at the values. class IsArgs { public: - IsArgs(unsigned int arg_count, CommandBufferEntry *args) + IsArgs(unsigned int arg_count, const void* args) : arg_count_(arg_count), - args_(args) { } + args_(static_cast<CommandBufferEntry*>(const_cast<void*>(args))) { } - bool operator() (CommandBufferEntry *args) const { + bool operator() (const void* _args) const { + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args); for (unsigned int i = 0; i < arg_count_; ++i) { if (args[i].value_uint32 != args_[i].value_uint32) return false; } @@ -77,7 +79,7 @@ class AsyncAPIMock : public AsyncAPIInterface { MOCK_METHOD3(DoCommand, BufferSyncInterface::ParseError( unsigned int command, unsigned int arg_count, - CommandBufferEntry *args)); + const void* args)); // Sets the engine, to forward SET_TOKEN commands to it. void set_engine(CommandBufferEngine *engine) { engine_ = engine; } @@ -85,10 +87,12 @@ class AsyncAPIMock : public AsyncAPIInterface { // Forwards the SetToken commands to the engine. void SetToken(unsigned int command, unsigned int arg_count, - CommandBufferEntry *args) { + const void* _args) { DCHECK(engine_); DCHECK_EQ(1, command); DCHECK_EQ(1, arg_count); + const CommandBufferEntry* args = + static_cast<const CommandBufferEntry*>(_args); engine_->set_token(args[0].value_uint32); } private: |